📜
connectionmanager_copy.js
Back
📝 Javascript ⚡ Executable Ctrl+S: Save • Ctrl+R: Run • Ctrl+F: Find
(function () { window.AppItems = window.AppItems || []; // --- Component: SFTP Connections --- const section = { title: "Connections", html: ` <div class="conn-container"> <div class="conn-header"> <h2 style="margin:0;">🔐 SFTP Connections</h2> <button class="conn-btn conn-btn-primary" onclick="openConnectionModal()">+ New Connection</button> </div> <div class="connections-grid" id="connectionsGrid"></div> </div> <!-- Add/Edit Connection Modal --> <div class="conn-modal" id="connectionModal" aria-hidden="true"> <div class="conn-modal__backdrop" onclick="closeConnectionModal()"></div> <div class="conn-modal__dialog"> <div class="conn-modal__header"> <h3 id="modalTitle">New Connection</h3> <button class="conn-close-btn" onclick="closeConnectionModal()">×</button> </div> <form id="connectionForm"> <input type="hidden" id="connectionId"> <div class="conn-form-group"> <label class="conn-label">Connection Name</label> <input type="text" class="conn-input" id="connName" placeholder="My Server" required> </div> <div class="conn-form-group"> <label class="conn-label">Host</label> <input type="text" class="conn-input" id="connHost" placeholder="files.devbrewing.com" required> </div> <div class="conn-form-group"> <label class="conn-label">Port</label> <input type="number" class="conn-input" id="connPort" value="22" required> </div> <div class="conn-form-group"> <label class="conn-label">Username</label> <input type="text" class="conn-input" id="connUser" required> </div> <div class="conn-form-group"> <label class="conn-label">Password</label> <div class="conn-pw-wrap"> <input type="password" class="conn-input" id="connPass" required> <button type="button" class="conn-pw-toggle" onclick="toggleConnPassword()">👁️</button> </div> </div> <div class="conn-form-actions"> <button type="submit" class="conn-btn conn-btn-primary">Save Connection</button> <button type="button" class="conn-btn conn-btn-secondary" onclick="closeConnectionModal()">Cancel</button> </div> <div id="formMessage"></div> </form> </div> </div> <!-- Toast Container --> <div class="conn-toast-container" id="connToastContainer"></div> <style> ${document.querySelector('style')?.textContent || ''} /* preserves all your CSS */ </style> ` }; window.AppItems.push(section); // --- Local Storage Key --- const STORAGE_KEY = 'sftp_connections'; // --- Helpers --- function getConnections() { const data = localStorage.getItem(STORAGE_KEY); return data ? JSON.parse(data) : []; } function saveConnections(list) { localStorage.setItem(STORAGE_KEY, JSON.stringify(list)); } function showToast(message, type = 'success', timeout = 2500) { const container = document.getElementById('connToastContainer'); if (!container) return; const toast = document.createElement('div'); toast.className = `conn-toast ${type}`; toast.textContent = message; container.appendChild(toast); setTimeout(() => { toast.style.animation = 'connToastOut 160ms ease forwards'; setTimeout(() => toast.remove(), 200); }, timeout); } // --- Modal Handlers --- window.openConnectionModal = function (id = null) { const modal = document.getElementById('connectionModal'); const form = document.getElementById('connectionForm'); const title = document.getElementById('modalTitle'); form.reset(); document.getElementById('formMessage').innerHTML = ''; const connections = getConnections(); if (id) { const conn = connections.find(c => c.id === id); if (conn) { title.textContent = 'Edit Connection'; document.getElementById('connectionId').value = conn.id; document.getElementById('connName').value = conn.name; document.getElementById('connHost').value = conn.host; document.getElementById('connPort').value = conn.port; document.getElementById('connUser').value = conn.username; document.getElementById('connPass').value = conn.password; } } else { title.textContent = 'New Connection'; } modal.setAttribute('aria-hidden', 'false'); }; window.closeConnectionModal = () => document.getElementById('connectionModal').setAttribute('aria-hidden', 'true'); window.toggleConnPassword = () => { const input = document.getElementById('connPass'); input.type = input.type === 'password' ? 'text' : 'password'; }; // --- Core Actions via AppStorage.driver --- async function connectToServer(conn, card) { try { card.classList.add('connecting'); const res = await AppStorage.driver.connect(conn); if (res.success) { const all = getConnections(); all.forEach(c => c.active = false); conn.active = true; saveConnections(all); renderConnections(); showToast(`✅ Connected to ${conn.name}`); } else throw new Error(res.message); } catch (err) { showToast(`❌ Connection failed: ${err.message}`, 'error'); } finally { card.classList.remove('connecting'); } } async function disconnectConnection(id) { try { await AppStorage.driver.disconnect(); const conns = getConnections(); conns.forEach(c => (c.active = false)); saveConnections(conns); renderConnections(); showToast('Disconnected successfully'); } catch (err) { showToast('Disconnect failed: ' + err.message, 'error'); } } // --- Render Connections --- function renderConnections() { const grid = document.getElementById('connectionsGrid'); if (!grid) return; grid.innerHTML = ''; const conns = getConnections(); conns.forEach(conn => { const card = document.createElement('div'); card.className = `conn-card ${conn.active ? 'active' : ''}`; card.innerHTML = ` <div class="conn-status-bar"></div> <div class="conn-card-header"> <div class="conn-card-title">${conn.name}</div> </div> <div class="conn-card-info"> ${conn.host}:${conn.port}<br>${conn.username} </div> <span class="conn-status-badge ${conn.active ? 'active' : 'inactive'}"> ${conn.active ? '🟢 Connected' : '⚫ Disconnected'} </span> `; card.addEventListener('click', () => conn.active ? disconnectConnection(conn.id) : connectToServer(conn, card) ); grid.appendChild(card); }); // Add connection button const addCard = document.createElement('div'); addCard.className = 'conn-card conn-add-card'; addCard.innerHTML = `<div class="conn-add-icon">+</div><div>Add Connection</div>`; addCard.addEventListener('click', () => openConnectionModal()); grid.appendChild(addCard); } // --- Form Submission --- document.addEventListener('submit', e => { if (e.target.id === 'connectionForm') { e.preventDefault(); const conns = getConnections(); const id = document.getElementById('connectionId').value || Date.now().toString(); const conn = { id, name: document.getElementById('connName').value, host: document.getElementById('connHost').value, port: parseInt(document.getElementById('connPort').value), username: document.getElementById('connUser').value, password: document.getElementById('connPass').value, active: false }; const existingIndex = conns.findIndex(c => c.id === id); if (existingIndex >= 0) conns[existingIndex] = conn; else conns.push(conn); saveConnections(conns); renderConnections(); closeConnectionModal(); showToast('Connection saved'); } }); // --- Initialize Render when overlay opens --- document.addEventListener('click', e => { const btn = e.target.closest('.chip'); if (btn && btn.textContent.includes('Connections')) { setTimeout(renderConnections, 100); } }); console.log('[connectionmanager.js] Cleaned up — uses SFTP driver via core'); })();