Filtro de Tabela [closed]

Fala galera, tenho o código abaixo que possui funções para filtrar os dados, mas ao clicar no filtro há uma demora para abrir, as vezes abre rápido outras vezes não abre o poderia melhorar?

Interface da Aplicação: (https://i.sstatic.net/9VAOMWKN.png)

Realizar uma filtragem rápida , mas o filtro tem problemas ao ser clicado.

const { ipcRenderer } = require('electron');

document.addEventListener("DOMContentLoaded", () => {
    const fileInput = document.getElementById("fileInput");
    const processButton = document.getElementById("processButton");

    // Elementos do cabeçalho para exibir as informações do associado
    const accountName = document.getElementById("accountName");
    const accountNumber = document.getElementById("accountNumber");
    const accountAddress = document.getElementById("accountAddress");
    const bairroCep = document.getElementById("bairroCep");
    const cityState = document.getElementById("cityState");
    const saldoDisponivel = document.getElementById("saldoDisponivel");
    const limiteChequeEspecial = document.getElementById("limiteChequeEspecial");
    const limiteUtilizado = document.getElementById("limiteUtilizado");

    const progressContainer = document.querySelector('.progress-container');
    const progressText = document.getElementById('progressText');

    // Elementos dos filtros
    const dateFilter = document.getElementById('filterDateDropdown');
    const docFilter = document.getElementById('filterDocDropdown');
    const histFilter = document.getElementById('filterHistDropdown');
    const debFilter = document.getElementById('filterDebDropdown');
    const credFilter = document.getElementById('filterCredDropdown');
    const saldoFilter = document.getElementById('filterSaldoDropdown');

    let allTransactions = []; // Variável para armazenar todas as transações carregadas
    let filteredTransactions = []; // Transações filtradas
    let selectedFilters = {}; // Armazena os valores selecionados de cada filtro

    // Função para mostrar o anel de progresso
    function showProgress() {
        progressContainer.style.opacity = '1';
    }

    // Função para esconder o anel de progresso
    function hideProgress() {
        setTimeout(() => {
            progressContainer.style.opacity = '0';
        }, 1000);
    }

    // Função para atualizar o texto do progresso
    function updateProgress(percentage) {
        progressText.textContent = `${percentage}%`;
    }

    // Função para limpar as transações antes de exibir novas
    function clearTransactions() {
        const transactionsTableBody = document.getElementById('transactionsTableBody');
        transactionsTableBody.innerHTML = ''; // Limpa as linhas antigas
    }

    // Função para exibir as transações
    function displayTransactions(transactions) {
        clearTransactions(); // Limpa transações anteriores
        const transactionsTableBody = document.getElementById('transactionsTableBody');

        transactions.forEach((transaction) => {
            const row = document.createElement('tr');

            // Crie as células da tabela com base nos dados da transação
            const dateCell = document.createElement('td');
            dateCell.textContent = transaction.date;

            const docCell = document.createElement('td');
            docCell.textContent = transaction.document;

            const histCell = document.createElement('td');
            histCell.textContent = transaction.historico;

            const debCell = document.createElement('td');
            debCell.textContent = transaction.debito;

            const credCell = document.createElement('td');
            credCell.textContent = transaction.credito;

            const saldoCell = document.createElement('td');
            saldoCell.textContent = transaction.saldo;

            // Adiciona as células à linha
            row.appendChild(dateCell);
            row.appendChild(docCell);
            row.appendChild(histCell);
            row.appendChild(debCell);
            row.appendChild(credCell);
            row.appendChild(saldoCell);

            // Adiciona a linha ao corpo da tabela
            transactionsTableBody.appendChild(row);
        });
    }

    // Função para popular os filtros com os valores únicos das transações (usando checkboxes)
    function populateFilters(transactions) {
        const dates = new Set();
        const docs = new Set();
        const hists = new Set();
        const debs = new Set();
        const creds = new Set();
        const saldos = new Set();

        transactions.forEach(transaction => {
            if (transaction.date) dates.add(transaction.date);
            if (transaction.document) docs.add(transaction.document);
            if (transaction.historico) hists.add(transaction.historico);
            if (transaction.debito) debs.add(transaction.debito);
            if (transaction.credito) creds.add(transaction.credito);
            if (transaction.saldo) saldos.add(transaction.saldo);
        });

        function createFilterOptions(set, filterDropdown, filterName) {
            filterDropdown.innerHTML = ''; // Limpa o dropdown atual

            const filterContainer = document.createElement('div');
            filterContainer.classList.add('filter-container');

            const search = document.createElement('input');
            search.type = 'text';
            search.placeholder = 'Pesquisar...';
            search.classList.add('dropdown-search');
            search.onkeyup = function () {
                filterDropdown.querySelectorAll('label').forEach(label => {
                    const text = label.textContent.toLowerCase();
                    const searchValue = search.value.toLowerCase();
                    label.style.display = text.includes(searchValue) ? '' : 'none';
                });
            };
            filterContainer.appendChild(search);

            const optionList = document.createElement('div');
            optionList.classList.add('option-list');  // Contêiner para opções com rolagem interna
            set.forEach(item => {
                const label = document.createElement('label');
                const checkbox = document.createElement('input');
                checkbox.type = 'checkbox';
                checkbox.value = item;

                // Marca a caixa de seleção se o item estiver no filtro selecionado
                if (selectedFilters[filterName] && selectedFilters[filterName].includes(item)) {
                    checkbox.checked = true;
                }

                label.appendChild(checkbox);
                label.appendChild(document.createTextNode(item));
                optionList.appendChild(label);
            });
            filterContainer.appendChild(optionList);

            const clearButton = document.createElement('button');
            clearButton.textContent = 'Limpar Filtros';
            clearButton.classList.add('clear-filter-button');
            clearButton.onclick = function() {
                clearAllFilters(); // Limpa todos os filtros
            };
            filterContainer.appendChild(clearButton);

            filterDropdown.appendChild(filterContainer);

            // Adiciona os botões OK e Cancelar
            const actionsContainer = document.createElement('div');
            actionsContainer.classList.add('filter-actions');

            const applyButton = document.createElement('button');
            applyButton.textContent = 'OK';
            applyButton.classList.add('apply-filter-button');
            applyButton.onclick = function() {
                applyFilters(filterDropdown, filterName); // Aplica os filtros do dropdown específico
                closeAllDropdowns(); // Fecha o dropdown após aplicar os filtros
            };

            const cancelButton = document.createElement('button');
            cancelButton.textContent = 'Cancelar';
            cancelButton.classList.add('cancel-filter-button');
            cancelButton.onclick = function() {
                closeAllDropdowns(); // Fecha sem aplicar
            };

            actionsContainer.appendChild(applyButton);
            actionsContainer.appendChild(cancelButton);
            filterContainer.appendChild(actionsContainer);
        }

        createFilterOptions(dates, dateFilter, 'date');
        createFilterOptions(docs, docFilter, 'doc');
        createFilterOptions(hists, histFilter, 'hist');
        createFilterOptions(debs, debFilter, 'deb');
        createFilterOptions(creds, credFilter, 'cred');
        createFilterOptions(saldos, saldoFilter, 'saldo');
    }

    // Função para aplicar os filtros de checkboxes e garantir a interdependência entre colunas
    function applyFilters(filterDropdown, filterName) {
        const getCheckedValues = () => {
            const checkboxes = filterDropdown.querySelectorAll('input[type="checkbox"]');
            const checkedValues = [];
            checkboxes.forEach(checkbox => {
                if (checkbox.checked) {
                    checkedValues.push(checkbox.value);
                }
            });
            return checkedValues.length > 0 ? checkedValues : null;
        };

        selectedFilters[filterName] = getCheckedValues(); // Armazena os valores selecionados no filtro

        filteredTransactions = allTransactions.filter(transaction => {
            const dateMatch = !selectedFilters.date || selectedFilters.date.includes(transaction.date);
            const docMatch = !selectedFilters.doc || selectedFilters.doc.includes(transaction.document);
            const histMatch = !selectedFilters.hist || selectedFilters.hist.includes(transaction.historico);
            const debMatch = !selectedFilters.deb || selectedFilters.deb.includes(transaction.debito);
            const credMatch = !selectedFilters.cred || selectedFilters.cred.includes(transaction.credito);
            const saldoMatch = !selectedFilters.saldo || selectedFilters.saldo.includes(transaction.saldo);

            return dateMatch && docMatch && histMatch && debMatch && credMatch && saldoMatch;
        });

        displayTransactions(filteredTransactions);
    }

    // Função para limpar todos os filtros
    function clearAllFilters() {
        selectedFilters = {}; // Limpa todos os filtros
        filteredTransactions = [...allTransactions]; // Restaura todas as transações
        displayTransactions(filteredTransactions); // Exibe todas as transações
        populateFilters(filteredTransactions); // Restaura os filtros para os valores completos
    }

    // Processar o arquivo ao clicar no botão "Processar"
    processButton.addEventListener("click", () => {
        const file = fileInput.files[0];
        if (!file) {
            alert("Selecione um arquivo .prn.");
            return;
        }

        showProgress(); // Exibe o anel de progresso

        let progress = 0;
        const interval = setInterval(() => {
            if (progress < 100) {
                progress += 10;
                updateProgress(progress);
            } else {
                clearInterval(interval);
                hideProgress(); // Esconde o anel de progresso
            }
        }, 300);

        const reader = new FileReader();
        reader.onload = function (event) {
            const content = event.target.result;

            // Envia o conteúdo para o processo principal (main.js) para ser processado
            ipcRenderer.send('process-file', content);
        };
        reader.readAsText(file);
    });

    // Recebe a resposta do Python via o processo principal
    ipcRenderer.on('file-processed', (event, data) => {
        const headerInfo = data.header_info;
        const transactions = data.transactions;

        // Exibe o cabeçalho
        accountName.textContent = headerInfo.name;
        accountNumber.textContent = headerInfo.account_number;
        accountAddress.textContent = headerInfo.address;
        bairroCep.textContent = headerInfo.bairro_cep;
        cityState.textContent = headerInfo.city_state;
        saldoDisponivel.textContent = headerInfo.saldo_disponivel;
        limiteChequeEspecial.textContent = headerInfo.limite_cheque_especial;
        limiteUtilizado.textContent = headerInfo.limite_utilizado;

        // Exibe as transações e popula os filtros
        allTransactions = transactions;
        filteredTransactions = transactions; // Inicialmente todas as transações são exibidas
        displayTransactions(transactions);
        populateFilters(transactions);
    });
});

// Função para mostrar/ocultar o dropdown de filtro
function toggleDropdown(dropdownId) {
    const dropdown = document.getElementById(dropdownId);
    
    // Fecha todos os dropdowns abertos antes de abrir o selecionado
    closeAllDropdowns();

    // Verifica se o dropdown já está visível
    if (!dropdown.classList.contains("show")) {
        dropdown.classList.add("show");
    }
}

// Função para fechar todos os dropdowns abertos
function closeAllDropdowns() {
    const dropdowns = document.getElementsByClassName("dropdown-content");
    for (let i = 0; i < dropdowns.length; i++) {
        dropdowns[i].classList.remove("show");
    }
}

// Evitar que o dropdown feche ao clicar dentro dele
document.querySelectorAll('.dropdown-content').forEach(dropdown => {
    dropdown.addEventListener('click', function(event) {
        event.stopPropagation(); // Impede o fechamento do dropdown ao clicar em elementos internos
    });
});

// Fecha o dropdown se o usuário clicar fora dele
window.onclick = function(event) {
    if (!event.target.matches('.filter-btn') && !event.target.matches('.filter-btn img')) {
        closeAllDropdowns();
    }
}