fix: auth default to password + remove SSH tab from assets
servers.html: Default auth method to "密码" (password) instead of "密钥" (key) when adding a new server. Hide key path row by default. assets.html: Remove SSH Sessions tab — it duplicated the server list functionality. Assets page now focuses on classification metadata: platform templates and node groups only. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
+2
-38
@@ -10,7 +10,6 @@
|
||||
<div class="bg-slate-900 border-b border-slate-800 px-6 flex">
|
||||
<button onclick="switchTab('platforms')" id="tabPlatforms" class="px-4 py-3 text-sm border-b-2 border-brand text-brand-light transition">平台模板</button>
|
||||
<button onclick="switchTab('nodes')" id="tabNodes" class="px-4 py-3 text-sm border-b-2 border-transparent text-slate-400 hover:text-white transition">节点分组</button>
|
||||
<button onclick="switchTab('sessions')" id="tabSessions" class="px-4 py-3 text-sm border-b-2 border-transparent text-slate-400 hover:text-white transition">SSH 会话</button>
|
||||
</div>
|
||||
<main class="flex-1 overflow-y-auto p-6">
|
||||
<!-- Platforms -->
|
||||
@@ -21,11 +20,6 @@
|
||||
<div id="nodesSection" class="hidden">
|
||||
<div id="nodesTree" class="space-y-1"><div class="text-slate-500 text-center py-8">加载中...</div></div>
|
||||
</div>
|
||||
<!-- SSH Sessions -->
|
||||
<div id="sessionsSection" class="hidden">
|
||||
<p class="text-slate-500 text-xs mb-3">双击服务器行打开SSH终端</p>
|
||||
<div id="sessionsList" class="space-y-2"><div class="text-slate-500 text-center py-8">加载中...</div></div>
|
||||
</div>
|
||||
|
||||
<!-- Platform Modal -->
|
||||
<div id="platformModal" class="hidden fixed inset-0 bg-black/60 flex items-center justify-center z-50">
|
||||
@@ -63,18 +57,16 @@
|
||||
let _allNodes=[];
|
||||
|
||||
function switchTab(t){
|
||||
const tabs=['platforms','nodes','sessions'];
|
||||
const tabs=['platforms','nodes'];
|
||||
tabs.forEach(x=>{
|
||||
document.getElementById('tab'+x.charAt(0).toUpperCase()+x.slice(1)).className='px-4 py-3 text-sm border-b-2 '+(x===t?'border-brand text-brand-light':'border-transparent text-slate-400 hover:text-white')+' transition';
|
||||
document.getElementById(x+'Section').classList.toggle('hidden',x!==t);
|
||||
});
|
||||
if(t==='nodes')loadNodes();
|
||||
if(t==='sessions')loadSessions();
|
||||
}
|
||||
|
||||
function showAddModal(){
|
||||
const tab=document.getElementById('platformsSection').classList.contains('hidden')?
|
||||
(document.getElementById('nodesSection').classList.contains('hidden')?null:'nodes'):'platforms';
|
||||
const tab=document.getElementById('platformsSection').classList.contains('hidden')?'nodes':'platforms';
|
||||
if(tab==='platforms')showAddPlatform();
|
||||
else if(tab==='nodes')showAddNode();
|
||||
}
|
||||
@@ -269,34 +261,6 @@
|
||||
loadNodes();
|
||||
}
|
||||
|
||||
// ── SSH Sessions ──
|
||||
async function loadSessions(){
|
||||
try{
|
||||
const srvR=await apiFetch(API+'/servers/?per_page=500');
|
||||
if(!srvR)return;
|
||||
const data=await srvR.json();
|
||||
const servers=data.items||data;
|
||||
if(!servers.length){document.getElementById('sessionsList').innerHTML='<div class="text-slate-500 text-center py-8">暂无服务器,请先添加服务器</div>';return}
|
||||
document.getElementById('sessionsList').innerHTML=servers.map(s=>{
|
||||
const hasSSH=s.domain?'':'opacity-50';
|
||||
const hint=s.domain?'双击连接':'未配置域名';
|
||||
return `<div class="bg-slate-900 rounded-xl border border-slate-800 p-3 flex items-center justify-between cursor-pointer hover:border-brand/40 transition ${hasSSH}" ondblclick="${s.domain?`window.open('/app/terminal.html?server_id='+${s.id})`:''}" title="${hint}">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="text-slate-500">🖥</span>
|
||||
<div>
|
||||
<span class="text-white text-sm">${esc(s.name)}</span>
|
||||
<span class="text-slate-500 text-xs ml-2">${esc(s.domain||'')}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right text-xs text-slate-500">
|
||||
<div>${esc(s.username||'root')}@${esc(s.domain||s.ip||'—')}</div>
|
||||
<div>${hint}</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}).join('');
|
||||
}catch(e){document.getElementById('sessionsList').innerHTML='<div class="text-red-400 text-center py-8">加载失败</div>'}
|
||||
}
|
||||
|
||||
function esc(s){if(!s)return'';const d=document.createElement('div');d.textContent=s;return d.innerHTML}
|
||||
function escAttr(s){if(!s)return'';return s.replace(/&/g,'&').replace(/"/g,'"').replace(/'/g,''').replace(/</g,'<').replace(/>/g,'>')}
|
||||
function fmtTime(t){if(!t)return'--';return new Date(t+'Z').toLocaleString('zh-CN',{month:'short',day:'numeric',hour:'2-digit',minute:'2-digit'})}
|
||||
|
||||
@@ -99,10 +99,10 @@
|
||||
<div class="grid grid-cols-3 gap-3">
|
||||
<div><label class="block text-slate-400 text-xs mb-1">SSH端口</label><input id="srvPort" type="number" value="22" class="w-full px-3 py-2 bg-slate-800 border border-slate-700 rounded-lg text-white text-sm"></div>
|
||||
<div><label class="block text-slate-400 text-xs mb-1">用户名</label><input id="srvUser" value="root" class="w-full px-3 py-2 bg-slate-800 border border-slate-700 rounded-lg text-white text-sm"></div>
|
||||
<div><label class="block text-slate-400 text-xs mb-1">认证方式</label><select id="srvAuth" class="w-full px-3 py-2 bg-slate-800 border border-slate-700 rounded-lg text-white text-sm"><option value="key">密钥</option><option value="password">密码</option></select></div>
|
||||
<div><label class="block text-slate-400 text-xs mb-1">认证方式</label><select id="srvAuth" class="w-full px-3 py-2 bg-slate-800 border border-slate-700 rounded-lg text-white text-sm"><option value="password">密码</option><option value="key">密钥</option></select></div>
|
||||
</div>
|
||||
<div id="srvPasswordRow"><label class="block text-slate-400 text-xs mb-1">密码</label><input id="srvPassword" type="password" class="w-full px-3 py-2 bg-slate-800 border border-slate-700 rounded-lg text-white text-sm" placeholder="SSH密码"></div>
|
||||
<div id="srvKeyPathRow"><label class="block text-slate-400 text-xs mb-1">密钥路径</label><input id="srvKeyPath" class="w-full px-3 py-2 bg-slate-800 border border-slate-700 rounded-lg text-white text-sm" placeholder="/root/.ssh/id_rsa"></div>
|
||||
<div id="srvKeyPathRow" class="hidden"><label class="block text-slate-400 text-xs mb-1">密钥路径</label><input id="srvKeyPath" class="w-full px-3 py-2 bg-slate-800 border border-slate-700 rounded-lg text-white text-sm" placeholder="/root/.ssh/id_rsa"></div>
|
||||
<!-- Agent -->
|
||||
<div class="text-slate-500 text-xs uppercase tracking-wider mt-3 mb-1">Agent</div>
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
@@ -446,7 +446,7 @@
|
||||
|
||||
async function deleteServer(id){if(!confirm('确定删除服务器 #'+id+'?'))return;const r=await apiFetch(API+'/servers/'+id,{method:'DELETE'});if(r&&r.ok)toast('success','服务器已删除');else toast('error','删除失败');if(selectedServerId===id)hideDetail();loadServers()}
|
||||
let _pendingAgentKey='';
|
||||
function showAddServer(){_pendingAgentKey='';document.getElementById('editServerId').value='';document.getElementById('modalTitle').textContent='添加服务器';['srvName','srvDomain','srvPassword','srvCategory','srvTarget','srvDesc','srvKeyPath','srvAgentKey'].forEach(id=>document.getElementById(id).value='');document.getElementById('srvAgentKey').placeholder='留空则使用全局 API Key';document.getElementById('srvPort').value='22';document.getElementById('srvUser').value='root';document.getElementById('srvAuth').value='key';document.getElementById('srvAgentPort').value='8601';document.getElementById('srvPlatform').value='';document.getElementById('srvNode').value='';toggleAuthFields();loadOrgSelects();document.getElementById('serverModal').classList.remove('hidden')}
|
||||
function showAddServer(){_pendingAgentKey='';document.getElementById('editServerId').value='';document.getElementById('modalTitle').textContent='添加服务器';['srvName','srvDomain','srvPassword','srvCategory','srvTarget','srvDesc','srvKeyPath','srvAgentKey'].forEach(id=>document.getElementById(id).value='');document.getElementById('srvAgentKey').placeholder='留空则使用全局 API Key';document.getElementById('srvPort').value='22';document.getElementById('srvUser').value='root';document.getElementById('srvAuth').value='password';document.getElementById('srvAgentPort').value='8601';document.getElementById('srvPlatform').value='';document.getElementById('srvNode').value='';toggleAuthFields();loadOrgSelects();document.getElementById('serverModal').classList.remove('hidden')}
|
||||
function showEditServer(id){const s=_serversCache[id];if(!s)return;document.getElementById('editServerId').value=s.id;document.getElementById('modalTitle').textContent='编辑服务器';document.getElementById('srvName').value=s.name||'';document.getElementById('srvDomain').value=s.domain||'';document.getElementById('srvPort').value=s.port||22;document.getElementById('srvUser').value=s.username||'root';document.getElementById('srvAuth').value=s.auth_method||'key';document.getElementById('srvPassword').value='';document.getElementById('srvKeyPath').value=s.ssh_key_path||'';document.getElementById('srvAgentPort').value=s.agent_port||8601;document.getElementById('srvAgentKey').value=_pendingAgentKey||'';document.getElementById('srvAgentKey').placeholder=s.agent_api_key_set&&!_pendingAgentKey?'已设置 — 留空不修改,点🔑重新生成':'留空则使用全局 API Key';document.getElementById('srvCategory').value=s.category||'';document.getElementById('srvTarget').value=s.target_path||'';document.getElementById('srvDesc').value=s.description||'';toggleAuthFields();loadOrgSelects().then(()=>{document.getElementById('srvPlatform').value=s.platform_id||'';document.getElementById('srvNode').value=s.node_id||''});document.getElementById('serverModal').classList.remove('hidden')}
|
||||
function hideServerModal(){document.getElementById('serverModal').classList.add('hidden')}
|
||||
function toggleAuthFields(){const isKey=document.getElementById('srvAuth').value==='key';document.getElementById('srvPasswordRow').style.display=isKey?'none':'';document.getElementById('srvKeyPathRow').style.display=isKey?'':'none'}
|
||||
|
||||
Reference in New Issue
Block a user