From 84ca74f04bd25124c2024e13689e3609c9340e3a Mon Sep 17 00:00:00 2001 From: pewdiepie-archdaemon Date: Tue, 9 Jun 2026 09:51:53 +0900 Subject: [PATCH] Restore cookbook server key exports --- static/js/cookbook.js | 52 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/static/js/cookbook.js b/static/js/cookbook.js index 03319d0de..9a1a09777 100644 --- a/static/js/cookbook.js +++ b/static/js/cookbook.js @@ -114,18 +114,45 @@ function _setCookbookOpening(on) { // True for the local server entry (empty / "local" / "localhost" host). function _isLocalEntry(s) { return !s || !s.host || s.host === 'local' || s.host.toLowerCase() === 'localhost'; } -// Resolve a dropdown option value to a server entry. Option values are the -// stable HOST string ('local' for the local box) — NOT array indices — because -// `_envState.servers` gets deduped/reordered, which made index-based selection -// silently resolve to the wrong (or local) server. Accepts a numeric index too -// for backwards-compat with any stale value. -function _serverByVal(val) { +// Resolve a dropdown option value to a server entry. New option values are +// stable per-profile keys, so same-host SSH profiles stay distinguishable. +// Host strings and numeric indices remain accepted for stale saved state. +export function _serverKey(s) { + if (_isLocalEntry(s)) return 'local'; + return 'srv:' + [ + s?.name || '', + s?.host || '', + s?.port || '', + s?.envPath || '', + s?.platform || '', + ].map(v => encodeURIComponent(String(v).trim())).join('|'); +} + +export function _serverByVal(val) { if (val == null || val === 'local' || val === '') return null; - let s = _envState.servers.find(x => x.host === val); + const raw = String(val); + let s = _envState.servers.find(x => _serverKey(x) === raw); + if (!s) s = _envState.servers.find(x => x.host === raw); + if (!s) s = _envState.servers.find(x => x.name === raw); if (!s && /^\d+$/.test(String(val))) s = _envState.servers[parseInt(val)]; return s || null; } +export function _selectedServer() { + if (_envState.remoteServerKey) { + const keyed = _serverByVal(_envState.remoteServerKey); + if (keyed) return keyed; + } + if (_envState.remoteHost) return _envState.servers.find(s => s.host === _envState.remoteHost) || null; + return null; +} + +export function _currentServerValue() { + const selected = _selectedServer(); + if (selected) return _serverKey(selected); + return _envState.remoteHost || 'local'; +} + function _buildServerOpts(excludeLocal = false) { // The local server is ALWAYS represented by the synthetic value="local" option // (showing its custom name from the "server name" feature). We must therefore @@ -134,13 +161,20 @@ function _buildServerOpts(excludeLocal = false) { const _localSrv = _localIdx >= 0 ? _envState.servers[_localIdx] : null; const _localLabel = (_localSrv && _localSrv.name) ? _localSrv.name : 'Local'; let html = ``; + const selectedKey = _envState.remoteServerKey || ''; + let legacyHostSelected = false; for (let i = 0; i < _envState.servers.length; i++) { const s = _envState.servers[i]; if (i === _localIdx) continue; // already the synthetic "local" option if (excludeLocal && _isLocalEntry(s)) continue; const label = s.name || s.host || `Server ${i + 1}`; - const selected = _envState.remoteHost === s.host ? ' selected' : ''; - html += ``; + const value = _serverKey(s); + let selected = selectedKey ? value === selectedKey : false; + if (!selectedKey && _envState.remoteHost === s.host && !legacyHostSelected) { + selected = true; + legacyHostSelected = true; + } + html += ``; } return html; }