let currentPage = 1; const rowsPerPage = 10; let paginatedData = []; function paginateData(data) { // Urutkan data berdasarkan yang terbaru (jika data punya timestamp, bisa urutkan dari sana) data = data.slice().reverse(); // Membalik urutan untuk menampilkan data terbaru dulu paginatedData = []; for (let i = 0; i < data.length; i += rowsPerPage) { paginatedData.push(data.slice(i, i + rowsPerPage)); } console.log('Paginated Data:', paginatedData); } function renderTable(page) { const tbody = document.querySelector('#resultTable tbody'); tbody.innerHTML = ''; // Hapus isi tabel sebelumnya if (!paginatedData[page - 1]) { console.error('Page data is undefined or empty:', paginatedData[page - 1]); return; // Prevents trying to render undefined data } paginatedData[page - 1].forEach((row) => { const tr = document.createElement('tr'); const dcuIpCell = document.createElement('td'); dcuIpCell.textContent = row['DCU IP'] || 'N/A'; tr.appendChild(dcuIpCell); const dcuIdCell = document.createElement('td'); dcuIdCell.textContent = row['DCU ID'] || 'N/A'; tr.appendChild(dcuIdCell); const updatedIpCell = document.createElement('td'); updatedIpCell.textContent = row['Updated IP'] || 'N/A'; tr.appendChild(updatedIpCell); const updateStatusCell = document.createElement('td'); updateStatusCell.textContent = row['Update Status'] || 'N/A'; tr.appendChild(updateStatusCell); tbody.appendChild(tr); }); document.getElementById('resultTable').style.display = 'table'; } function updatePaginationControls() { const paginationContainer = document.getElementById('pagination'); paginationContainer.innerHTML = ''; for (let i = 1; i <= paginatedData.length; i++) { const pageButton = document.createElement('button'); pageButton.textContent = i; pageButton.className = 'page-button'; if (i === currentPage) pageButton.classList.add('active'); pageButton.addEventListener('click', () => { currentPage = i; renderTable(currentPage); updatePaginationControls(); }); paginationContainer.appendChild(pageButton); } } // Fungsi untuk menghitung total IP yang diinputkan document.getElementById('ipList').addEventListener('input', () => { const ipList = document.getElementById('ipList').value; fetch('/count-ips', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ ipList }), }) .then(response => response.json()) .then(data => { document.getElementById('totalList').textContent = data.total; document.getElementById('totalList').setAttribute('data-total', data.total); // Simpan nilai di atribut data }) .catch(err => { console.error('Error:', err); }); }); let processRunning = false; // Status apakah proses sedang berjalan document.getElementById('runScriptForm').addEventListener('submit', async (event) => { event.preventDefault(); const startButton = document.querySelector('.start-button'); const loadingIndicator = document.getElementById('loadingIndicator'); if (processRunning) { // Jika tombol Stop ditekan, tampilkan konfirmasi untuk menghentikan proses const userConfirm = confirm("Apakah Anda yakin ingin menghentikan proses yang sedang berjalan?"); if (userConfirm) { try { // Kirim permintaan untuk menghentikan proses await fetch('/stop-script', { method: 'POST' }); processRunning = false; startButton.textContent = 'Start'; startButton.style.backgroundColor = ''; // Kembalikan ke warna semula loadingIndicator.style.display = 'none'; alert('Proses telah dihentikan.'); } catch (error) { alert('Gagal menghentikan proses.'); } } } else { // Jika tombol Start ditekan processRunning = true; // Ambil list IP yang dimasukkan const ipList = document.getElementById('ipList').value; const ipArray = ipList.split(/\n|,/).map(ip => ip.trim()).filter(Boolean); // Tampilkan loading indicator dan ubah tombol menjadi Stop loadingIndicator.style.display = 'block'; startButton.textContent = 'Processing'; startButton.style.backgroundColor = '#e69500'; // Kirim data IP list ke server const response = await fetch('/run-script', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ ipList: ipArray }) }); if (!response.ok) { alert('Script is already running or an error occurred.'); processRunning = false; startButton.textContent = 'Start'; startButton.style.backgroundColor = ''; // Kembalikan ke warna semula loadingIndicator.style.display = 'none'; return; } const result = await response.json(); // Setelah proses selesai, perbarui tabel dan status loadingIndicator.style.display = 'none'; paginateData(result.processedData); renderTable(currentPage); updatePaginationControls(); const total = document.getElementById('totalList').getAttribute('data-total'); document.getElementById('processStatus').style.display = 'block'; document.getElementById('processStatus').textContent = `Finish. Processed IP ${result.processedData.length} of ${total}`; document.getElementById('resultTable').style.display = 'table'; document.getElementById('totalProcessed').textContent = `Total Processed: ${result.totalProcessed}`; document.getElementById('totalProcessed').style.display = 'block'; // Reset tombol kembali ke Start setelah selesai processRunning = false; startButton.textContent = 'Start'; startButton.style.backgroundColor = ''; } }); // WebSocket connection for real-time updates const socket = io(); // Reference to the log output area const logOutput = document.getElementById('logOutput'); // Listen for 'logUpdate' events and append log data socket.on('logUpdate', (logData) => { logOutput.value += logData; logOutput.scrollTop = logOutput.scrollHeight; // Scroll to the latest entry }); // Listen for 'logComplete' event to notify when logging is done socket.on('logComplete', (message) => { logOutput.value += '\n' + message; logOutput.scrollTop = logOutput.scrollHeight; }); // Listen for 'tableUpdate' events and update the table in real time const resultTableBody = document.querySelector('#resultTable tbody'); socket.on('tableUpdate', (updatedData) => { console.log('Received table update:', updatedData); // Debug log if (!Array.isArray(updatedData)) { console.error('Updated data is not an array:', updatedData); return; // Ensure it's an array before processing } currentPage = 1; // Reset ke halaman pertama setiap kali data baru diterima // Panggil fungsi paginateData untuk memproses pagination dengan data baru paginateData(updatedData); // Render tabel pada halaman pertama renderTable(currentPage); // Perbarui kontrol pagination agar sesuai dengan data terbaru updatePaginationControls(); // Update total processed count jika diperlukan const totalProcessed = document.getElementById('totalProcessed'); totalProcessed.textContent = `Total Processed: ${updatedData.length}`; totalProcessed.style.display = 'block'; });