window.ConnectionsManagement = (function() { 'use strict'; var endpoints = {}; var csrfToken = ''; function init(config) { endpoints = config.endpoints || {}; csrfToken = config.csrfToken || ''; setupEventListeners(); checkAllConnectionHealth(); } function togglePassword(id) { var input = document.getElementById(id); if (input) { input.type = input.type === 'password' ? 'text' : 'password'; } } async function testConnection(formId, resultId) { var form = document.getElementById(formId); var resultDiv = document.getElementById(resultId); if (!form || !resultDiv) return; var formData = new FormData(form); var data = {}; formData.forEach(function(value, key) { if (key !== 'csrf_token') { data[key] = value; } }); resultDiv.innerHTML = '
Testing connection...
'; var controller = new AbortController(); var timeoutId = setTimeout(function() { controller.abort(); }, 20000); try { var response = await fetch(endpoints.test, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': csrfToken }, body: JSON.stringify(data), signal: controller.signal }); clearTimeout(timeoutId); var result = await response.json(); if (response.ok) { resultDiv.innerHTML = '
' + '' + '' + '' + window.UICore.escapeHtml(result.message) + '
'; } else { resultDiv.innerHTML = '
' + '' + '' + '' + window.UICore.escapeHtml(result.message) + '
'; } } catch (error) { clearTimeout(timeoutId); var message = error.name === 'AbortError' ? 'Connection test timed out - endpoint may be unreachable' : 'Connection failed: Network error'; resultDiv.innerHTML = '
' + '' + '' + '' + message + '
'; } } async function checkConnectionHealth(connectionId, statusEl) { if (!statusEl) return; try { var controller = new AbortController(); var timeoutId = setTimeout(function() { controller.abort(); }, 15000); var response = await fetch(endpoints.healthTemplate.replace('CONNECTION_ID', connectionId), { signal: controller.signal }); clearTimeout(timeoutId); var data = await response.json(); if (data.healthy) { statusEl.innerHTML = '' + ''; statusEl.setAttribute('data-status', 'healthy'); statusEl.setAttribute('title', 'Connected'); } else { statusEl.innerHTML = '' + ''; statusEl.setAttribute('data-status', 'unhealthy'); statusEl.setAttribute('title', data.error || 'Unreachable'); } } catch (error) { statusEl.innerHTML = '' + ''; statusEl.setAttribute('data-status', 'unknown'); statusEl.setAttribute('title', 'Could not check status'); } } function checkAllConnectionHealth() { var rows = document.querySelectorAll('tr[data-connection-id]'); rows.forEach(function(row, index) { var connectionId = row.getAttribute('data-connection-id'); var statusEl = row.querySelector('.connection-status'); if (statusEl) { setTimeout(function() { checkConnectionHealth(connectionId, statusEl); }, index * 200); } }); } function updateConnectionCount() { var countBadge = document.querySelector('.badge.bg-primary.bg-opacity-10.text-primary.fs-6'); if (countBadge) { var remaining = document.querySelectorAll('tr[data-connection-id]').length; countBadge.textContent = remaining + ' connection' + (remaining !== 1 ? 's' : ''); } } function createConnectionRowHtml(conn) { var ak = conn.access_key || ''; var maskedKey = ak.length > 12 ? ak.slice(0, 8) + '...' + ak.slice(-4) : ak; return '' + '' + '' + '' + '' + '
' + '
' + '
' + '' + window.UICore.escapeHtml(conn.name) + '' + '
' + '' + window.UICore.escapeHtml(conn.endpoint_url) + '' + '' + window.UICore.escapeHtml(conn.region) + '' + '' + window.UICore.escapeHtml(maskedKey) + '' + '
' + '' + '' + '
'; } function setupEventListeners() { var testBtn = document.getElementById('testConnectionBtn'); if (testBtn) { testBtn.addEventListener('click', function() { testConnection('createConnectionForm', 'testResult'); }); } var editTestBtn = document.getElementById('editTestConnectionBtn'); if (editTestBtn) { editTestBtn.addEventListener('click', function() { testConnection('editConnectionForm', 'editTestResult'); }); } var editModal = document.getElementById('editConnectionModal'); if (editModal) { editModal.addEventListener('show.bs.modal', function(event) { var button = event.relatedTarget; if (!button) return; var id = button.getAttribute('data-id'); document.getElementById('edit_name').value = button.getAttribute('data-name') || ''; document.getElementById('edit_endpoint_url').value = button.getAttribute('data-endpoint') || ''; document.getElementById('edit_region').value = button.getAttribute('data-region') || ''; document.getElementById('edit_access_key').value = button.getAttribute('data-access') || ''; document.getElementById('edit_secret_key').value = button.getAttribute('data-secret') || ''; document.getElementById('editTestResult').innerHTML = ''; var form = document.getElementById('editConnectionForm'); form.action = endpoints.updateTemplate.replace('CONNECTION_ID', id); }); } var deleteModal = document.getElementById('deleteConnectionModal'); if (deleteModal) { deleteModal.addEventListener('show.bs.modal', function(event) { var button = event.relatedTarget; if (!button) return; var id = button.getAttribute('data-id'); var name = button.getAttribute('data-name'); document.getElementById('deleteConnectionName').textContent = name; var form = document.getElementById('deleteConnectionForm'); form.action = endpoints.deleteTemplate.replace('CONNECTION_ID', id); }); } var createForm = document.getElementById('createConnectionForm'); if (createForm) { createForm.addEventListener('submit', function(e) { e.preventDefault(); window.UICore.submitFormAjax(createForm, { successMessage: 'Connection created', onSuccess: function(data) { createForm.reset(); document.getElementById('testResult').innerHTML = ''; if (data.connection) { var emptyState = document.querySelector('.empty-state'); if (emptyState) { var cardBody = emptyState.closest('.card-body'); if (cardBody) { cardBody.innerHTML = '
' + '' + '' + '' + '' + '' + '
StatusNameEndpointRegionAccess KeyActions
'; } } var tbody = document.querySelector('table tbody'); if (tbody) { tbody.insertAdjacentHTML('beforeend', createConnectionRowHtml(data.connection)); var newRow = tbody.lastElementChild; var statusEl = newRow.querySelector('.connection-status'); if (statusEl) { checkConnectionHealth(data.connection.id, statusEl); } } updateConnectionCount(); } else { location.reload(); } } }); }); } var editForm = document.getElementById('editConnectionForm'); if (editForm) { editForm.addEventListener('submit', function(e) { e.preventDefault(); window.UICore.submitFormAjax(editForm, { successMessage: 'Connection updated', onSuccess: function(data) { var modal = bootstrap.Modal.getInstance(document.getElementById('editConnectionModal')); if (modal) modal.hide(); var connId = editForm.action.split('/').slice(-2)[0]; var row = document.querySelector('tr[data-connection-id="' + connId + '"]'); if (row && data.connection) { var nameCell = row.querySelector('.fw-medium'); if (nameCell) nameCell.textContent = data.connection.name; var endpointCell = row.querySelector('.text-truncate'); if (endpointCell) { endpointCell.textContent = data.connection.endpoint_url; endpointCell.title = data.connection.endpoint_url; } var regionBadge = row.querySelector('.badge.bg-primary'); if (regionBadge) regionBadge.textContent = data.connection.region; var accessCode = row.querySelector('code.small'); if (accessCode && data.connection.access_key) { var ak = data.connection.access_key; accessCode.textContent = ak.slice(0, 8) + '...' + ak.slice(-4); } var editBtn = row.querySelector('[data-bs-target="#editConnectionModal"]'); if (editBtn) { editBtn.setAttribute('data-name', data.connection.name); editBtn.setAttribute('data-endpoint', data.connection.endpoint_url); editBtn.setAttribute('data-region', data.connection.region); editBtn.setAttribute('data-access', data.connection.access_key); if (data.connection.secret_key) { editBtn.setAttribute('data-secret', data.connection.secret_key); } } var deleteBtn = row.querySelector('[data-bs-target="#deleteConnectionModal"]'); if (deleteBtn) { deleteBtn.setAttribute('data-name', data.connection.name); } var statusEl = row.querySelector('.connection-status'); if (statusEl) { checkConnectionHealth(connId, statusEl); } } } }); }); } var deleteForm = document.getElementById('deleteConnectionForm'); if (deleteForm) { deleteForm.addEventListener('submit', function(e) { e.preventDefault(); window.UICore.submitFormAjax(deleteForm, { successMessage: 'Connection deleted', onSuccess: function(data) { var modal = bootstrap.Modal.getInstance(document.getElementById('deleteConnectionModal')); if (modal) modal.hide(); var connId = deleteForm.action.split('/').slice(-2)[0]; var row = document.querySelector('tr[data-connection-id="' + connId + '"]'); if (row) { row.remove(); } updateConnectionCount(); if (document.querySelectorAll('tr[data-connection-id]').length === 0) { location.reload(); } } }); }); } } return { init: init, togglePassword: togglePassword, testConnection: testConnection, checkConnectionHealth: checkConnectionHealth }; })();