Alterações visuais das tabelas - Relatório Contábil
This commit is contained in:
parent
7651ae23be
commit
fcd5a70579
@ -4099,7 +4099,7 @@ class ContabilApuracaoViewSet(viewsets.ModelViewSet):
|
||||
{
|
||||
"detail": (
|
||||
"O arquivo não está no formato esperado (Balancete + DRE do Questor). "
|
||||
"Contate a Integração e Inovação."
|
||||
"Contate o setor de Inovação."
|
||||
)
|
||||
},
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
@ -4199,7 +4199,7 @@ class ContabilApuracaoViewSet(viewsets.ModelViewSet):
|
||||
if apuracao is not None:
|
||||
apuracao.arquivo.delete(save=False)
|
||||
return Response(
|
||||
{"detail": "Não foi possível salvar a análise. Contate a Integração e Inovação."},
|
||||
{"detail": "Não foi possível salvar a análise. Contate o setor de Inovação."},
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
|
||||
@ -4262,7 +4262,7 @@ class ContabilApuracaoViewSet(viewsets.ModelViewSet):
|
||||
{
|
||||
"detail": (
|
||||
"O arquivo não está no formato esperado (Balancete + DRE do Questor). "
|
||||
"Contate a Integração e Inovação."
|
||||
"Contate o setor de Inovação."
|
||||
)
|
||||
},
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
@ -4305,7 +4305,7 @@ class ContabilApuracaoViewSet(viewsets.ModelViewSet):
|
||||
if novo_arquivo_salvo:
|
||||
apuracao.arquivo.delete(save=False)
|
||||
return Response(
|
||||
{"detail": "Não foi possível reprocessar a análise. Contate a Integração e Inovação."},
|
||||
{"detail": "Não foi possível reprocessar a análise. Contate o setor de Inovação."},
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
|
||||
|
||||
@ -67,6 +67,27 @@
|
||||
border-radius: var(--radius-md);
|
||||
}
|
||||
|
||||
.dc-list-pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: var(--space-3);
|
||||
margin-top: var(--space-4);
|
||||
}
|
||||
|
||||
.dc-list-pagination__info {
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* Quantidade de registros do histórico, abaixo da paginação. */
|
||||
.dc-list-count {
|
||||
text-align: center;
|
||||
font-size: 0.8rem;
|
||||
color: var(--text-muted);
|
||||
margin-top: var(--space-2);
|
||||
}
|
||||
|
||||
/* Ordenação + filtro "estilo Excel" por coluna do histórico (#dc-list-table)
|
||||
— mesmo mecanismo/classes de .ips-* em importacao-plano-saude.css, só
|
||||
renomeado pro prefixo desta página (não compartilhado entre os dois
|
||||
@ -251,6 +272,34 @@
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Barra de progresso de "Nova Análise"/"Reprocessar" — mostrada enquanto o
|
||||
PDF é processado de forma síncrona no backend (sem fila de tarefas, não há
|
||||
um percentual real pra reportar); a subida até ~90% é simulada em JS
|
||||
(pidDcIniciarProgressoSimulado) e só fecha os últimos 10% quando a
|
||||
resposta volta de verdade, ver dashboard-contabil.js. */
|
||||
.dc-progress__bar {
|
||||
width: 100%;
|
||||
height: 6px;
|
||||
border-radius: var(--radius-pill);
|
||||
background: var(--border-subtle);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.dc-progress__fill {
|
||||
height: 100%;
|
||||
width: 0%;
|
||||
border-radius: inherit;
|
||||
background: var(--accent);
|
||||
transition: width 0.2s ease-out;
|
||||
}
|
||||
|
||||
.dc-progress__label {
|
||||
margin-top: var(--space-2);
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Log de reprocessamentos anteriores, dentro do modal "Reprocessar análise"
|
||||
— reaproveita .dc-obs-resumo__titulo/__count (mesmo "título + contagem em
|
||||
pílula" já usado no resumo de observações por aba), só a lista em si é
|
||||
|
||||
@ -174,6 +174,32 @@ function pidDcEscapeHtml(texto) {
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
// Barra de progresso de "Nova Análise"/"Reprocessar" — o processamento roda
|
||||
// de forma síncrona numa única requisição (sem fila de tarefas), então não
|
||||
// existe um percentual real pra reportar. Simula a subida: cresce rápido no
|
||||
// início e desacelera perto de 90%, sem nunca chegar lá sozinha — só
|
||||
// `completar()` (chamado quando a resposta volta) fecha os últimos 10% e
|
||||
// segura em 100% por um instante, pra sempre refletir o fim de verdade do
|
||||
// processamento, nunca um término fake antes da hora.
|
||||
function pidDcIniciarProgressoSimulado(fillEl) {
|
||||
let pct = 0;
|
||||
fillEl.style.width = "0%";
|
||||
const intervalId = setInterval(() => {
|
||||
pct += (90 - pct) * 0.1;
|
||||
fillEl.style.width = `${pct}%`;
|
||||
}, 200);
|
||||
return {
|
||||
parar() {
|
||||
clearInterval(intervalId);
|
||||
},
|
||||
async completar() {
|
||||
clearInterval(intervalId);
|
||||
fillEl.style.width = "100%";
|
||||
await new Promise((resolve) => setTimeout(resolve, 300));
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Posiciona o `<span class="dc-hover-tooltip__texto">` (fixed, ver
|
||||
// dashboard-contabil.css) relativo à viewport, calculado no momento do
|
||||
// hover/foco — nasce acima do gatilho, centralizado; sem espaço acima
|
||||
@ -463,14 +489,20 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
// Ordenação + filtro "estilo Excel" do histórico (#dc-list-table) — mesmo
|
||||
// mecanismo de listSortKey/listSortDir/listFiltros em
|
||||
// importacao-plano-saude.js: client-side, sobre o array já carregado
|
||||
// (dcListaApuracoes), sem repaginar nem refazer fetch a cada mudança.
|
||||
// (dcListaApuracoes), sem refazer fetch a cada mudança. A paginação
|
||||
// (dcListPage/DC_LIST_PAGE_SIZE) também segue o mesmo padrão de
|
||||
// importacao-plano-saude.js (IPS_LIST_PAGE_SIZE/renderListPagination).
|
||||
let dcListaApuracoes = [];
|
||||
let dcListSortKey = "criado_em";
|
||||
let dcListSortDir = -1;
|
||||
// null = sem filtro nessa coluna; senão, um Set com os valores marcados no
|
||||
// popup daquela coluna (combinam entre si por E lógico).
|
||||
let dcListFiltros = { empresa: null, competencia: null, status: null, criado_por: null };
|
||||
let dcListPage = 1;
|
||||
const DC_LIST_PAGE_SIZE = 10;
|
||||
const dcListSortHeaders = Array.from(document.querySelectorAll("#dc-list-table th[data-sort]"));
|
||||
const dcListPagination = document.getElementById("dc-list-pagination");
|
||||
const dcListCount = document.getElementById("dc-list-count");
|
||||
|
||||
function showView(view) {
|
||||
listView.hidden = view !== "list";
|
||||
@ -529,6 +561,18 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
renderList();
|
||||
}
|
||||
|
||||
function dcRenderListPagination(totalPaginas) {
|
||||
if (!dcListPagination) return;
|
||||
if (totalPaginas <= 1) {
|
||||
dcListPagination.innerHTML = "";
|
||||
return;
|
||||
}
|
||||
dcListPagination.innerHTML = `
|
||||
<button type="button" class="btn-outline" id="dc-list-prev-btn" ${dcListPage === 1 ? "disabled" : ""}>Página anterior</button>
|
||||
<span class="dc-list-pagination__info">Página ${dcListPage} de ${totalPaginas}</span>
|
||||
<button type="button" class="btn-outline" id="dc-list-next-btn" ${dcListPage === totalPaginas ? "disabled" : ""}>Próxima página</button>`;
|
||||
}
|
||||
|
||||
function renderList() {
|
||||
const body = document.getElementById("dc-list-body");
|
||||
const empty = document.getElementById("dc-list-empty");
|
||||
@ -543,8 +587,13 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
const extrator = PID_DC_LISTA_SORT_VALOR[dcListSortKey];
|
||||
const ordenadas = [...filtradas].sort((a, b) => dcComparaValoresLista(extrator(a), extrator(b)) * dcListSortDir);
|
||||
|
||||
const totalPaginas = Math.max(1, Math.ceil(ordenadas.length / DC_LIST_PAGE_SIZE));
|
||||
dcListPage = Math.min(dcListPage, totalPaginas);
|
||||
const inicio = (dcListPage - 1) * DC_LIST_PAGE_SIZE;
|
||||
const pagina = ordenadas.slice(inicio, inicio + DC_LIST_PAGE_SIZE);
|
||||
|
||||
body.innerHTML = "";
|
||||
ordenadas.forEach((apuracao) => {
|
||||
pagina.forEach((apuracao) => {
|
||||
const tr = document.createElement("tr");
|
||||
tr.innerHTML = `
|
||||
<td>${pidDcEscapeHtml(apuracao.codigo_empresa)} - ${pidDcEscapeHtml(apuracao.nome_empresa)} ${pidDcFontePdfAtipicaBadgeHtml(apuracao.fonte_pdf_atipica)}</td>
|
||||
@ -579,6 +628,17 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
th.classList.toggle("is-sort-asc", key === dcListSortKey && dcListSortDir === 1);
|
||||
th.classList.toggle("is-sort-desc", key === dcListSortKey && dcListSortDir === -1);
|
||||
});
|
||||
|
||||
dcRenderListPagination(totalPaginas);
|
||||
|
||||
if (dcListCount) {
|
||||
if (ordenadas.length === 0) {
|
||||
dcListCount.textContent = "";
|
||||
} else {
|
||||
const fim = Math.min(inicio + DC_LIST_PAGE_SIZE, ordenadas.length);
|
||||
dcListCount.textContent = `Mostrando ${inicio + 1}–${fim} de ${ordenadas.length} registro${ordenadas.length === 1 ? "" : "s"}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dcListSortHeaders.forEach((th) => {
|
||||
@ -594,6 +654,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
dcListSortKey = key;
|
||||
dcListSortDir = 1;
|
||||
}
|
||||
dcListPage = 1;
|
||||
renderList();
|
||||
});
|
||||
});
|
||||
@ -728,6 +789,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
dcListFiltros[campo] = null;
|
||||
fechar();
|
||||
atualizarBotaoAtivo();
|
||||
dcListPage = 1;
|
||||
renderList();
|
||||
});
|
||||
|
||||
@ -740,6 +802,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
dcListFiltros[campo] = marcouTudo ? null : new Set(marcados);
|
||||
fechar();
|
||||
atualizarBotaoAtivo();
|
||||
dcListPage = 1;
|
||||
renderList();
|
||||
});
|
||||
|
||||
@ -756,6 +819,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
dcListSortDir = -1;
|
||||
dcListFiltros = { empresa: null, competencia: null, status: null, criado_por: null };
|
||||
dcFiltrosColuna.forEach((f) => f.atualizarBotaoAtivo());
|
||||
dcListPage = 1;
|
||||
renderList();
|
||||
});
|
||||
}
|
||||
@ -764,6 +828,18 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
if (!event.target.closest(".dc-col-filter")) dcFecharTodosOsFiltrosColuna();
|
||||
});
|
||||
|
||||
if (dcListPagination) {
|
||||
dcListPagination.addEventListener("click", (event) => {
|
||||
if (event.target.closest("#dc-list-prev-btn")) {
|
||||
dcListPage -= 1;
|
||||
renderList();
|
||||
} else if (event.target.closest("#dc-list-next-btn")) {
|
||||
dcListPage += 1;
|
||||
renderList();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById("dc-list-body").addEventListener("click", async (event) => {
|
||||
const abrirBtn = event.target.closest("[data-dc-abrir]");
|
||||
if (abrirBtn) {
|
||||
@ -859,9 +935,15 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
formData.append("arquivo", arquivo);
|
||||
|
||||
const confirmarBtn = document.getElementById("dc-reprocessar-confirmar-btn");
|
||||
const cancelarBtn = document.getElementById("dc-reprocessar-cancel-btn");
|
||||
const progressEl = document.getElementById("dc-reprocessar-progress");
|
||||
confirmarBtn.disabled = true;
|
||||
cancelarBtn.disabled = true;
|
||||
progressEl.hidden = false;
|
||||
const progresso = pidDcIniciarProgressoSimulado(progressEl.querySelector(".dc-progress__fill"));
|
||||
try {
|
||||
const atualizada = await pidReprocessarApuracaoContabil(dcReprocessarApuracaoId, formData);
|
||||
await progresso.completar();
|
||||
fecharReprocessarModal();
|
||||
await carregarLista();
|
||||
// Se a apuração reprocessada é a que já está aberta na tela de
|
||||
@ -878,9 +960,12 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
}
|
||||
await pidAlert("Análise reprocessada com sucesso.");
|
||||
} catch (e) {
|
||||
progresso.parar();
|
||||
errorEl.textContent = e.message;
|
||||
} finally {
|
||||
confirmarBtn.disabled = false;
|
||||
cancelarBtn.disabled = false;
|
||||
progressEl.hidden = true;
|
||||
}
|
||||
});
|
||||
|
||||
@ -932,9 +1017,17 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
formData.append("arquivo", arquivo);
|
||||
|
||||
const submitBtn = document.getElementById("dc-form-submit-btn");
|
||||
const cancelBtn = document.getElementById("dc-form-cancel-btn");
|
||||
const backBtn = document.getElementById("dc-form-back-btn");
|
||||
const progressEl = document.getElementById("dc-form-progress");
|
||||
submitBtn.disabled = true;
|
||||
cancelBtn.disabled = true;
|
||||
backBtn.disabled = true;
|
||||
progressEl.hidden = false;
|
||||
const progresso = pidDcIniciarProgressoSimulado(progressEl.querySelector(".dc-progress__fill"));
|
||||
try {
|
||||
const apuracao = await pidCriarApuracaoContabil(formData);
|
||||
await progresso.completar();
|
||||
apuracaoAtual = apuracao;
|
||||
await dcCarregarObservacoes();
|
||||
filtroSeveridade = "todas";
|
||||
@ -944,9 +1037,13 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
showView("review");
|
||||
await carregarLista();
|
||||
} catch (e) {
|
||||
progresso.parar();
|
||||
errorEl.textContent = e.message;
|
||||
} finally {
|
||||
submitBtn.disabled = false;
|
||||
cancelBtn.disabled = false;
|
||||
backBtn.disabled = false;
|
||||
progressEl.hidden = true;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -363,6 +363,8 @@
|
||||
</table>
|
||||
</div>
|
||||
<p class="dc-empty" id="dc-list-empty" hidden>Nenhuma análise realizada ainda.</p>
|
||||
<div class="dc-list-pagination" id="dc-list-pagination"></div>
|
||||
<p class="dc-list-count" id="dc-list-count"></p>
|
||||
</div>
|
||||
|
||||
<div id="dc-form-view" hidden>
|
||||
@ -390,6 +392,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<p class="modal-error" id="dc-form-error"></p>
|
||||
<div class="dc-progress" id="dc-form-progress" hidden>
|
||||
<div class="dc-progress__bar"><div class="dc-progress__fill"></div></div>
|
||||
<p class="dc-progress__label">Processando o arquivo, aguarde...</p>
|
||||
</div>
|
||||
<div class="modal-actions">
|
||||
<button type="button" class="btn-outline" id="dc-form-cancel-btn">Cancelar</button>
|
||||
<button type="button" class="btn-solid" id="dc-form-submit-btn">Processar</button>
|
||||
@ -624,6 +630,10 @@
|
||||
<ul class="dc-reprocessar-log__lista" id="dc-reprocessar-log-lista"></ul>
|
||||
</section>
|
||||
<p class="modal-error" id="dc-reprocessar-error"></p>
|
||||
<div class="dc-progress" id="dc-reprocessar-progress" hidden>
|
||||
<div class="dc-progress__bar"><div class="dc-progress__fill"></div></div>
|
||||
<p class="dc-progress__label">Processando o arquivo, aguarde...</p>
|
||||
</div>
|
||||
<div class="modal-actions">
|
||||
<button type="button" class="btn-outline" id="dc-reprocessar-cancel-btn">Cancelar</button>
|
||||
<button type="button" class="btn-solid" id="dc-reprocessar-confirmar-btn">Reprocessar</button>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user