Fix out-of-order pagination responses in the treatment table
pg-prev/pg-next deliberately skip comCarregando (it would fight the page-boundary disabled-state logic), so nothing stopped two rapid clicks from firing overlapping GET /api/leads requests. If the earlier page's response resolved after the later one, it silently overwrote the table, pager text and prev/next disabled state with a page the operator was no longer viewing. Adds a per-call sequence number in carregarTabela(); a response is only applied if no newer call has started since, covering every caller (pager clicks, filter changes, tab activation) with one guard. Found via a full-project audit; verified the regression test fails against the pre-fix code and passes against the fix.
This commit is contained in:
@@ -4,6 +4,7 @@ const Tratamento = (() => {
|
||||
let totalPages = 1;
|
||||
let carregado = false;
|
||||
let refreshTimer = null;
|
||||
let tabelaRequestSeq = 0;
|
||||
|
||||
const CLASSIFICACAO_LABELS = {
|
||||
excelente: 'Excelente', bom: 'Bom', medio: 'Médio', baixo: 'Baixo', muito_baixo: 'Muito Baixo'
|
||||
@@ -364,7 +365,13 @@ const Tratamento = (() => {
|
||||
}
|
||||
|
||||
async function carregarTabela() {
|
||||
const requestId = ++tabelaRequestSeq;
|
||||
const data = await API.get(`/api/leads?${filtroQuery({ page, pageSize: 50 })}`);
|
||||
// Descarta respostas fora de ordem: pg-prev/pg-next nao usam comCarregando
|
||||
// (ver bindEvents), entao um clique rapido pode disparar uma nova consulta
|
||||
// antes da anterior responder. Sem isso, a resposta mais lenta podia
|
||||
// sobrescrever a tabela/paginacao com uma pagina que ja nao e mais a atual.
|
||||
if (requestId !== tabelaRequestSeq) return;
|
||||
totalPages = Math.max(1, Math.ceil(data.total / data.pageSize));
|
||||
el('leads-total').textContent = `— ${fmt.format(data.total)} encontrados`;
|
||||
el('pg-info').textContent = `página ${data.page} de ${fmt.format(totalPages)}`;
|
||||
|
||||
Reference in New Issue
Block a user