The message received from the server could not be parse

Olá,

poderiam me ajudar a compreender o motivo deste erro ?

The message received from the server could not be parsed. Common causes for this error are when the response is modified by calls to Response.Write(), response filters, HttpModules, or server trace is enabled.
Details: Error parsing near ’

Olá @Gabriel, tudo bem?

Este erro ocorre em que momento?

Você poderia anexar um screenshot como referência?

1 curtida

Olá, @daniel. giacomelli ! Este erro estava aparecendo ao clicar em qualquer button, depois de algum tempo o sistema apresentou “RunTime Server”. Após a solução, não apareceu mais.

Reparei que alguns scripts JS que são adicionados em “Arquivos JavaScript”, não estão mais carregando no header.

Confere por favor, se nas Configurações do Site, a opção chamada “Proteção Anti-bot” está desabilitada.

Após a solução, não apareceu mais

Pelo que entendi, o problema deixou de ocorrer. Foi isso mesmo?

Reparei que alguns scripts JS que são adicionados em “Arquivos JavaScript”, não estão mais carregando no header.

Verifique se aparece algum erro de JavaScript no Console do navegador (F12). Se sim, compartilhe com a gente.

Pelo que entendi, o problema deixou de ocorrer. Foi isso mesmo?

Isso mesmo, após a estabilização do server o erro não apareceu mais.

Verifique se aparece algum erro de JavaScript no Console do navegador (F12). Se sim, compartilhe com a gente.

No console em si, não aparece nada. Mas utilizando a inspeção das fontes, aparentemente o arquivo não está sendo carregado.

image

Acredito que essa mensagem não deva causar nenhum problema.

O seu arquivo JS está sendo executado? Pode colocar um alert(...) ou debugger para testar.

O seu arquivo JS está sendo executado? Pode colocar um alert(...) ou debugger para testar.

O alert() carregou, porém não consigo utilizar as functions em scripts carregados no body posteriormente.

eu consegui solucionar migrando tudo para o formload

Compartilha com a gente o código do seu arquivo JS por favor.

let dadosOriginais = [];
let chart = null;
let dadosFiltrados = [];
let perdas = null;
let bool_sla = false;

alert('teste');

function calcularTempoPermanencia(entrada, saida) {
    const agora = new Date();
    //console.log(saida);
    // usa a saida informada ou agora
    saida = (saida == '' || saida == null) ? agora : saida;
    //console.log(saida);
    if (!(entrada instanceof Date) || isNaN(entrada)) return 0;
    if (!(saida instanceof Date) || isNaN(saida)) return 0;

    const diffMs = saida - entrada;
    const diffHoras = diffMs / (1000 * 60 * 60);
    return Math.max(diffHoras, 0);
}

function date_f_iso_8601() {
    
    const agora = new Date();
    
    const ano = agora.getFullYear();
    const mes = String(agora.getMonth() + 1).padStart(2, '0'); // Meses são baseados em zero
    const dia = String(agora.getDate()).padStart(2, '0');
    const horas = String(agora.getHours()).padStart(2, '0');
    const minutos = String(agora.getMinutes()).padStart(2, '0');
    const segundos = String(agora.getSeconds()).padStart(2, '0');
    
    const dataFormatada = `${ano}-${mes}-${dia}T${horas}:${minutos}:${segundos}`;
    return dataFormatada

}

function splitTextVertical(text) {
    return text.split('').join('\n');
}

function renderizarGrafico(dados, sla) {
  const agrupados = {};
  const agora = new Date();
  const target = 5;

  dados.forEach(item => {
    const prog = new Date(item.programacao_dt);

    // usar SEMPRE data_entrada / data_saida
    const entradaRaw = new Date(item.data_entrada);
    const saida = item.data_saida != '' ? new Date(item.data_saida) : new Date(agora);

    if (isNaN(prog) || isNaN(entradaRaw) || isNaN(saida)) return;

    // aplicar SLA (se pedido)
    const entradaCorrigida = sla && entradaRaw < prog ? prog : entradaRaw;

    const dataFormatada = saida.toLocaleDateString('pt-BR');
    const horas = sla
      ? (saida >= prog ? calcularTempoPermanencia(entradaCorrigida, saida) : 0)
      : calcularTempoPermanencia(entradaCorrigida, saida);

    const aderente = item.aderencia === true || String(item.aderencia).toLowerCase() === 'true';

    if (!agrupados[dataFormatada]) {
      agrupados[dataFormatada] = { totalHoras: 0, quantidade: 0, aderentes: 0 };
    }

    if (Number.isFinite(horas)) agrupados[dataFormatada].totalHoras += horas;
    agrupados[dataFormatada].quantidade += 1;
    if (aderente) agrupados[dataFormatada].aderentes += 1;
  });

  // Agora ordenamos as datas
    const categorias = Object.keys(agrupados).sort((a, b) => {
        const [diaA, mesA, anoA] = a.split('/').map(Number);
        const [diaB, mesB, anoB] = b.split('/').map(Number);
        const dateA = new Date(anoA, mesA - 1, diaA);
        const dateB = new Date(anoB, mesB - 1, diaB);
        return dateA - dateB;
    });

    const valores = categorias.map(data => {
        const { totalHoras, quantidade } = agrupados[data];
        const media = totalHoras / quantidade;
        return media;
    });
    
    const aderencias = categorias.map(data => {
        const { aderentes, quantidade } = agrupados[data];
        return quantidade > 0 ? parseFloat(((aderentes / quantidade) * 100).toFixed(2)) : 0;
    });

    const options = {
        chart: {
            /*type: 'bar',*/
            height: 400,
            width: '100%',
            toolbar: { show: false }
        },
        plotOptions: {
            bar: {
                columnWidth: '40%',
                borderRadius: 4,
                dataLabels: {
                    position: 'bottom',
                    orientation: 'vertical'
                }
            }
        },
        title: {
            text: '',
            align: 'center',
            style: {
                fontSize: '20px',
                color: '#003369'
            }
        },
        series: [
            {
                name: 'Média de Permanência',
                type: 'bar',
                data: valores
            },
            {
                name: '% Aderência',
                type: 'line',
                data: aderencias,
                yAxisIndex: 1
            }
        ],
        xaxis: {
            categories: categorias,
            labels: {
                rotate: -45,
            }
        },
        yaxis: [
            {
                min: 0,
                max: 12,
                tickAmount: 6,
                labels: {
                    rotateAlways: true,
                    formatter: function (val) {
                        const horas = Math.floor(val);
                        const minutos = Math.round((val - horas) * 60);
                        return `${horas}h ${minutos}m`;
                    }
                }
            },
            {
                opposite: true,
                title: { text: '% Aderência' },
                min: 0,
                max: 100,
                tickAmount: 5,
                labels: {
                    formatter: val => `${val.toFixed(0)}%`
                }
            }
        ],
        grid: {
            borderColor: '#e0e0e0',
            strokeDashArray: 4,
        },
        colors: ['#003369', '#bfdbff'],
        tooltip: {
            y: {
                formatter: function (val) {
                    const horas = Math.floor(val);
                    const minutos = Math.round((val - horas) * 60);
                    return `${horas}h ${minutos}m`;
                }
            }
        },
        dataLabels: {
            enabled: true,
            enabledOnSeries: [0, 1],
            formatter: function (val, { seriesIndex }) {
                if (seriesIndex === 0) {
                    // Série da média de permanência (em horas)
                    const h = Math.floor(val);
                    const m = Math.round((val - h) * 60);
                    return `${h}h ${m}m`;
                } else {
                    // Série da aderência (em porcentagem)
                    return `${val.toFixed(0)}%`;
                }
            },
            style: {
                colors: ['#0072ca'], // cor do texto (branco em cima da barra azul)
                fontSize: '12pt',
                fontWeight: 'bold',
            },
            background: {
                enabled: true // para não ter caixinha cinza atrás
            }
        },
        tooltip: {
            y: [
                {
                    formatter: val => {
                        const h = Math.floor(val);
                        const m = Math.round((val - h) * 60);
                        return `${h}h ${m}m`;
                    }
                },
                {
                    formatter: val => `${val.toFixed(0)}%`
                }
            ]
        },
        
        annotations: {
          yaxis: [
            {
              y: 5,
              opacity: 1,
              strokeDashArray: 3,
              borderColor: '#ffc238',
              label: {
                borderColor: '#ffc238',
                textAnchor: 'end',
                style: {
                  color: '#333',
                  background: '#ffc238',
                  padding: {
                    left: 5,
                    right: 5,
                    top: 0,
                    bottom: 2,
                  }
                },
                text: 'Target TAT'
              }
            }
          ]
        }
        
    };

    if (chart) {
        chart.destroy();
    }

    chart = new ApexCharts(document.querySelector("#chart"), options);
    chart.render();
}

function montarPerdas(dadosFiltrados, agora) {
    perdas = dadosFiltrados.filter(item => item.aderencia === false);
    perdas = perdas.map(item => {
        const entrada = new Date(item.data_entrada);
        const saida = item.data_saida ? new Date(item.data_saida) : new Date(agora);
        const diffHoras = (saida - entrada) / (1000 * 60 * 60); // ms → horas
        return {
            ...item,
            permanencia: formatarHorasMinutos(diffHoras)
        }
    });
    //console.log(perdas);
}

//Aplica filtros baseado no flag sla
function aplicarFiltros(sla) {
    //const filtroParqueado = document.getElementById('filtro-parqueado')?.value || 'todos';
    const filtroParqueado = document.querySelector('input[name="filtro-parqueado"]:checked')?.value || 'todos';
    const filtroDataInicio = document.getElementById('filtro-data-inicio')?.value;
    const filtroDataFim = document.getElementById('filtro-data-fim')?.value;

    dadosFiltrados = [...dadosOriginais];
    //console.log(dadosFiltrados);
    const target = 5; // horas
    const agora = date_f_iso_8601();
    
    if (filtroParqueado !== 'todos') {
        const parqueadoBool = filtroParqueado === 'true';
        dadosFiltrados = dadosFiltrados.filter(item => item.parqueado === parqueadoBool);
    }

    if (filtroDataInicio && filtroDataFim) {
        
        const dataInicio = new Date(`${filtroDataInicio}T00:00:00`);
        const dataFim = new Date(`${filtroDataFim}T23:59:59`);
        
        dadosFiltrados = dadosFiltrados.filter(item => {
            const entrada = new Date(item.data_saida ? item.data_saida : agora);
            return entrada >= dataInicio && entrada <= dataFim;
        });
    }
   
    //Adiciona a propriedade "aderencia" a cada item filtrado, considerando flag sla
    dadosFiltrados = dadosFiltrados.map(item => {
        
        var entrada = new Date(item.data_entrada); const prog = new Date(item.programacao_dt);
        if(sla) entrada = entrada < prog ? prog : entrada;
        
        const saida = item.data_saida ? new Date(item.data_saida) : new Date(agora);
        
        const diffHoras = Math.max(0 , saida - entrada) / (1000 * 60 * 60); // ms → horas - Math.max garante que o diff não seja negativo
        
        const aderente = () => {
            if(sla) {

                if (saida < prog) {
                    return true
                } else {
                    return diffHoras < target;
                }
            } 
            
            return diffHoras < target;
        };
        return {
            ...item,
            aderencia: aderente()
        };
    });

    console.log('Dados Filtrados', dadosFiltrados);
    //console.log(dadosFiltrados)
    
    renderizarGrafico(dadosFiltrados, sla); // Considerando sla
    preencherResumo(dadosFiltrados); // Considerando sla
    preencherOfensores(dadosFiltrados);
    montarPerdas(dadosFiltrados, agora);
    
    const projecao = calcularProjecao_aderencia(dadosOriginais, dadosFiltrados, 85.1);
    const calc_new_meta = calcular_nova_meta(dadosFiltrados, projecao.mediaMensal );
    const total_agora = dadosFiltrados.length

    
    document.getElementById('new_meta').innerHTML = `
        <h2> ${calc_new_meta}</h2>
    `;
    
    document.getElementById('projecao').innerHTML = `
        <div class="card destaque projecao">
            <strong>Projeção Não Parqueados</strong><br>
            
            Aderência esperada: <b>${projecao.meta}%</b><br>
            <br>
                <b>Carros até agora:</b> ${total_agora}<br>
                <b>Perdas até agora:</b> ${projecao.perdasOcorridas}<br>
                <b>Máximo permitido:</b> ${projecao.perdasMaximas}<br>
                <b>Média considerada: ${projecao.mediaMensal} ocorrências/mês
        </div>
    `;

}

// --- calcularMediaTempo (tat_dev) ---
function calcularMediaTempo(dados, sla) {

  if (dados.length === 0) return 0;

  // quando houver SLA, só considerar casos com saida >= prog (como você faz no gráfico)
  const dadosValidos = sla ? dados.filter(it => {
  
        const saida = it.data_saida == '' ? new Date() : new Date(it.data_saida);
        return saida >= new Date(it.programacao_dt)
    
   }) : dados;
  
  // Reduce irá trazer a somatoria total de horas
  const totalHoras = dadosValidos.reduce((acc, item) => {
  
        const prog = new Date(item.programacao_dt);
        const entradaRaw = new Date(item.data_entrada);
        const saida = item.data_saida == '' ? new Date() : new Date(item.data_saida);
        const entradaCorrigida = sla && entradaRaw < prog ? prog : entradaRaw;
        const horas = sla ? (saida >= prog ? calcularTempoPermanencia(entradaCorrigida, saida) : 0)
                          : calcularTempoPermanencia(entradaCorrigida, saida);
        //console.log(acc, horas);
        return acc + horas;
        
  }, 0);

  return dadosValidos.length ? totalHoras / dadosValidos.length : 0;
}

function calcularAderenciaPercentual(array) {
    const total = array.length;
    const aderentes = array.filter(item => item.aderencia === true).length;
    return total > 0 ? ((aderentes / total) * 100).toFixed(0) : 0;
}

function getClasseAderencia(valor) {
    if (valor >= 85) return 'alta';
    if (valor >= 70) return 'media';
    return 'baixa';
}

function formatarHorasMinutos(valorHoras) {
    const horas = Math.floor(valorHoras);
    const minutos = Math.round((valorHoras - horas) * 60);
    return `${horas}h ${minutos}m`;
}

// Preenche o resumo considerando o flag sla
function preencherResumo(dadosFiltrados, sla) {

    const hoje = new Date();
    const hojeInicio = new Date(hoje.getFullYear(), hoje.getMonth(), hoje.getDate(), 0, 0, 0);
    const hojeFim = new Date(hoje.getFullYear(), hoje.getMonth(), hoje.getDate(), 23, 59, 59);

    const dadosHoje = dadosFiltrados.filter(item => {
        const agora = new Date();
        const saida = new Date(item.data_saida ? item.data_saida : agora);
        return saida >= hojeInicio && saida <= hojeFim;
    });
    

    const dadosHojeParqueados = dadosHoje.filter(item => item.parqueado);
    const dadosHojeNaoParqueados = dadosHoje.filter(item => !item.parqueado);

    const mediaHojeGeral = calcularMediaTempo(dadosHoje, bool_sla); 
    const mediaHojeParqueados = calcularMediaTempo(dadosHojeParqueados, bool_sla);
    const mediaHojeNaoParqueados = calcularMediaTempo(dadosHojeNaoParqueados, bool_sla);
    
    //Aderencia Hoje
    const aderenciaHojeGeral = calcularAderenciaPercentual(dadosHoje);
    const aderenciaHojeParqueados = calcularAderenciaPercentual(dadosHojeParqueados);
    const aderenciaHojeNaoParqueados = calcularAderenciaPercentual(dadosHojeNaoParqueados);
     
    // Para Mensal, considerar intervalo completo filtrad
    const dadosMesParqueados = dadosFiltrados.filter(item => item.parqueado);
    const dadosMesNaoParqueados = dadosFiltrados.filter(item => !item.parqueado);

    const mediaMesGeral = calcularMediaTempo(dadosFiltrados, bool_sla);
    const mediaMesParqueados = calcularMediaTempo(dadosMesParqueados, bool_sla);
    const mediaMesNaoParqueados = calcularMediaTempo(dadosMesNaoParqueados, bool_sla);
    
    // Aderência Mensal
    const aderenciaMesGeral = calcularAderenciaPercentual(dadosFiltrados);
    const aderenciaMesParqueados = calcularAderenciaPercentual(dadosMesParqueados);
    const aderenciaMesNaoParqueados = calcularAderenciaPercentual(dadosMesNaoParqueados);

    // Preencher Hoje
    document.getElementById('resumo-hoje').innerHTML = `
        <div class="card">
            <strong>Geral</strong><br>${formatarHorasMinutos(mediaHojeGeral)}
            <br>
            <span class="aderencia ${getClasseAderencia(aderenciaHojeGeral)}">Aderência: ${aderenciaHojeGeral}%</span>
        </div>
        <div class="card">
            <strong>Parqueados</strong><br>${formatarHorasMinutos(mediaHojeParqueados)}
            <br>
            <span class="aderencia ${getClasseAderencia(aderenciaHojeParqueados)}">Aderência: ${aderenciaHojeParqueados}%</span>
        </div>
        <div class="card">
            <strong>Não Parqueados</strong><br>${formatarHorasMinutos(mediaHojeNaoParqueados)}
            <br>
            <span class="aderencia ${getClasseAderencia(aderenciaHojeNaoParqueados)} ">Aderência: ${aderenciaHojeNaoParqueados}%</span>
        </div>
    `;

    // Preencher Mensal
    document.getElementById('resumo-mes').innerHTML = `
        <div class="card">
            <strong>Geral</strong><br>${formatarHorasMinutos(mediaMesGeral)}
            <br><span class="aderencia ${getClasseAderencia(aderenciaMesGeral)} ">Aderência: ${aderenciaMesGeral}%</span>
        </div>
        <div class="card">
            <strong>Parqueados</strong><br>${formatarHorasMinutos(mediaMesParqueados)}
            <br><span class="aderencia ${getClasseAderencia(aderenciaMesParqueados)}">Aderência: ${aderenciaMesParqueados}%</span>
        </div>
        <div class="card">
            <strong>Não Parqueados</strong><br>${formatarHorasMinutos(mediaMesNaoParqueados)}
            <br><span class="aderencia ${getClasseAderencia(aderenciaMesNaoParqueados)} ">Aderência: ${aderenciaMesNaoParqueados}%</span>
        </div>
        
    `;
}

function preencherOfensores(dadosFiltrados) {
    const hoje = new Date();
    const hojeInicio = new Date(hoje.getFullYear(), hoje.getMonth(), hoje.getDate(), 0, 0, 0);
    const hojeFim = new Date(hoje.getFullYear(), hoje.getMonth(), hoje.getDate(), 23, 59, 59);
    
    const ofensoresHoje = dadosFiltrados.filter(item => {
        
        const entrada = new Date(item.data_entrada);
        const saida = item.data_saida == '' ? null : new Date(item.data_saida);
        const permanenciaHoras = calcularTempoPermanencia(entrada, saida);

        return (
            //entrada >= hojeInicio &&
            //entrada <= hojeFim &&
            item.parqueado == false &&
            !item.data_saida &&           // Ainda em aberto
            permanenciaHoras > 3           // Permanência maior que 5 horas
        );
    });
    

    // Ordenar ofensores do maior para o menor tempo
    ofensoresHoje.sort((a, b) => {
        const permanenciaA = calcularTempoPermanencia(new Date(a.data_entrada), null);
        const permanenciaB = calcularTempoPermanencia(new Date(b.data_entrada), null);
        return permanenciaB - permanenciaA;
    });

    const listaOfensores = document.getElementById('lista-ofensores');
    listaOfensores.innerHTML = '';

    if (ofensoresHoje.length === 0) {
    
        listaOfensores.innerHTML = '<p>Sem ofensores no momento.</p>';
        
    } else {
    
        ofensoresHoje.forEach(item => {
        
            const entrada = new Date(item.data_entrada)
            const div = document.createElement('div');
            var parq = item.parqueado == true ? ' - Parqueado' : ''; // texto para veiculos parqueados
            var status = item.status;
            var permanenciaHoras = calcularTempoPermanencia(entrada, null);
            
            // O card padrão é Yellow cargas com mais de 5 são criticas, então o card passa a ser red
            var cor = null;
            if ( permanenciaHoras > 5 ) {
                cor = 'red'
            }
            div.className = 'card-ofensor';
            div.classList.add(cor); 
            
            div.innerHTML = `
                <span>${item.dt} - ${status} - ${formatarHorasMinutos(permanenciaHoras)} ${parq}</span>
            `;
            listaOfensores.appendChild(div);
        });
    }
}

function calcular_nova_meta(dados, total_veiculos_considerar ) {

    const dadosNaoParqueados = dados.filter(item => !item.parqueado);
    const meta = 5;
    const total_veiculos_atual = dadosNaoParqueados.length;
    const horas_tat_atual = calcularMediaTempo(dados);
    //console.log(horas_tat_atual);
    
    const gastoAteAgora = total_veiculos_atual * horas_tat_atual; // TAT total até o momento
 
    if ( total_veiculos_atual <= total_veiculos_considerar ) {
    
        const restante = total_veiculos_considerar - total_veiculos_atual;
        const metaTotal = total_veiculos_considerar * meta;
        const mediaNecessaria = ( metaTotal - gastoAteAgora) / restante;
        
        if (horas_tat_atual <= meta) {
            return [`Sua média atual de ${formatarHorasMinutos(horas_tat_atual)} está abaixo da meta de ${meta}h. Continue assim!`];
        }
        
        if (mediaNecessaria < 0) {
            return "A meta já foi ultrapassada. Não é possível atingi-la com os atendimentos restantes.";
        }

        if (mediaNecessaria > meta) {
            return "Mesmo zerando o tempo nos próximos atendimentos, não é mais possível atingir a meta.";
        }
        
        const horasNecessarias = Math.floor(mediaNecessaria);
        const minutosNecessario = Math.floor(mediaNecessaria % 60);
        
        return `Você precisa manter média de até ${formatarHorasMinutos(mediaNecessaria)} nos próximos ${restante} atendimentos para atingir a meta de ${metaHoras}h.`;
    }
    
    // Caso de projeção com 4h
    const numerador = gastoAteAgora - (meta * total_veiculos_atual);
    const divisor = meta - 4;

    if (numerador <= 0) {
        return "Mesmo com excesso de atendimentos, sua média já está dentro da meta.";
    }

    if (divisor <= 0) {
        return "Parâmetros inválidos. A meta precisa ser maior que 4h para projeção funcionar.";
    }

    const n = Math.ceil(numerador / divisor);

    return `Você precisaria atender aproximadamente ${n} carros a 4h de média para que sua média total fique em ${meta}h.`;

}

function calcularProjecao_aderencia(dadosHistorico, dadosMesAtualComAderencia, meta = 86) {
    const agora = new Date();


    // Último dia do mês anterior
    const fimUltimoMes = new Date(agora.getFullYear(), agora.getMonth(), 0, 23, 59, 59);
    
    // Primeiro dia de 3 meses antes
    const inicioTresMesesAtras = new Date(fimUltimoMes.getFullYear(), fimUltimoMes.getMonth() - 2, 1, 0, 0, 0);

    // Filtrar últimos 3 meses do histórico
    const dadosUltimos3Meses = dadosHistorico.filter(item => {
        const dataBase = new Date(item.data_saida || date_f_iso_8601());
        return dataBase >= inicioTresMesesAtras && dataBase <= fimUltimoMes && !item.parqueado;
    });

    // Agrupar por mês
    const porMes = {};
    dadosUltimos3Meses.forEach(item => {
        const dataBase = new Date(item.data_saida || date_f_iso_8601());
        const chave = `${dataBase.getFullYear()}-${dataBase.getMonth()}`; // Ex: "2025-6"
        if (!porMes[chave]) porMes[chave] = [];
        porMes[chave].push(item);
    });

    const totalMeses = Object.keys(porMes).length;
    const somaOcorrencias = Object.values(porMes).reduce((acc, lista) => acc + lista.length, 0);
    const mediaOcorrenciasPorMes = totalMeses > 0 ? somaOcorrencias / totalMeses : 0; 
    
    

    const totalProjetadoMesAtual = Math.round(mediaOcorrenciasPorMes,2);
    const perdasPermitidas = Math.floor(totalProjetadoMesAtual * (1 - meta / 100));

    // Usar os dados filtrados do mês atual para contar as perdas com base na aderência já computada
    const perdasOcorridas = dadosMesAtualComAderencia.filter(item => item.aderencia === false).length;

    return {
        mediaMensal: Math.round(mediaOcorrenciasPorMes),
        projetadoMesAtual: totalProjetadoMesAtual,
        perdasMaximas: perdasPermitidas,
        perdasOcorridas,
        meta
    };
}


function converterParaCSV(objArray, separador = ",") {
  const array = typeof objArray !== 'object' ? JSON.parse(objArray) : objArray;

  // Cabeçalho
  const cabecalho = Object.keys(array[0]).join(separador);

  // Conteúdo
  const linhas = array.map(obj =>
    Object.values(obj)
      .map(valor => `"${String(valor).replace(/"/g, '""')}"`) // escapa aspas
      .join(separador)
  );

  return [cabecalho, ...linhas].join("\r\n");
}

function baixarCSV(dados, title) {
  const csv = converterParaCSV(dados, ";"); // Use ";" se quiser separado por ponto e vírgula
  const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
  const url = URL.createObjectURL(blob);

  const link = document.createElement("a");
  link.setAttribute("href", url);
  link.setAttribute("download", `${title}_tat.csv`);
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
}

// ===== Botão sla ==== //

function switchsla(btn) {
    bool_sla = !bool_sla;
    btn.className = bool_sla ? 'active' : 'deactivate';
    btn.textContent = bool_sla ? 'SLA - Ativado' : 'SLA - Desativado';
    
    aplicarFiltros(bool_sla);
}

Parece que está faltando um ponto de inicialização para o seu Script.

O ponto adequado para iniciar o processamento de qualquer código é após o carregamento completo do Formulário, que ocorre no evento formCreated.

Clicando com o botão direito do mouse sobre o editor de JavaScript, você encontrará algumas opções de snippet. Clique em “Javascript para Formulário”.

Abaixo o código que gerado, e as marcações de onde você deve alterar:

//
// --> Todo o código anteiror aqui
//

const myForm = (function () {

    // Adiciona Callbacks no Formulário
    latromi.formManager.setOnFormCreatedCallback(onFormCreated);
    latromi.formManager.setOnEventFiringCallback(onEventFiring);
    latromi.formManager.setOnFieldValueChangedCallback(onFieldValueChanged);

    // Ocorre logo após o form ser inicializado
    function onFormCreated(ev) { 
        //
        // --> Chame as suas funções aqui
        //
    }

    // Ocorre quando um evento é disparado no Form
    function onEventFiring(ev) { }

    // Ocorre quando o valor de um campo é alterado no Form
    function onFieldValueChanged(ev) { }

    // Todas as funções acima são "privadas", e não podem ser chamadas externamente.
    // As únicas funções que podem ser chamadas externamente são as que compões o resultado a seguir:
    return {
        test: function() { }
    }
})();