UI: instance list with names+status, click to select, v1.0.39

This commit is contained in:
2026-07-26 08:05:45 +04:00
parent 9668f03d3e
commit b0ef0c98fe
2 changed files with 41 additions and 26 deletions
+40 -25
View File
@@ -92,22 +92,20 @@
</div>
<script>
let selectedSvc=null, selectedOp=null, svcInstances=[];
let selectedSvc=null, selectedOp=null, svcInstances=[], selectedInst=null;
// Load services — only dummy for now
(async function(){
const el=document.getElementById('svc-list');
try{
const r=await fetch('/api/services');
const data=await r.json();
const dummy=data.find(s=>s.svcId===1);
if(dummy) el.innerHTML=`<div class="svc-item active" data-svc-id="1" onclick="selectService(1)">1. ${dummy.svc}</div>`;
selectService(1);
el.innerHTML=data.map(s=>`<div class="svc-item" data-svc-id="${s.svcId}" onclick="selectService(${s.svcId})">${s.svcId}. ${s.svc}</div>`).join('');
if(data.length>0) selectService(data[0].svcId);
}catch(e){el.innerHTML='<span style="color:var(--destructive);font-size:11px;">Ошибка загрузки</span>';}
})();
async function selectService(svcId){
selectedSvc=svcId; selectedOp=null;
selectedSvc=svcId; selectedOp=null; selectedInst=null;
document.querySelectorAll('.svc-item').forEach(e=>e.classList.toggle('active',e.dataset.svcId==String(svcId)));
document.getElementById('params-card').style.display='none';
document.getElementById('btn-test').style.display='none';
@@ -115,24 +113,43 @@ async function selectService(svcId){
const r=await fetch('/api/operations/'+svcId);
const d=await r.json();
svcInstances=d.instances||[];
const hasInstance=svcInstances.length>0;
const activeStatuses=svcInstances.map(i=>i.explainedStatus);
const opsCard=document.getElementById('ops-card');
opsCard.style.display='block';
document.getElementById('ops-card').style.display='block';
document.getElementById('ops-title').textContent=d.svc+' — операции';
const opsList=document.getElementById('ops-list');
opsList.innerHTML=d.operations.filter(o=>o.operation!=='reconcile').map(o=>{
let disabled=!hasInstance && o.operation!=='create';
if(hasInstance && o.operation==='create') disabled=true;
if(o.operation==='reconcile') disabled=false;
const cls=disabled?'op-item disabled':'op-item';
const btn=disabled?'':'<button class="btn btn-primary btn-sm" onclick="selectOperation('+o.svcOperationId+',\''+o.operation+'\','+svcId+')">Тест</button>';
const hint=disabled?`<span style="font-size:10px;color:var(--muted);">${hasInstance?'уже есть':'нет инстанса'}</span>`:'';
const instUid=svcInstances.length>0?`<span style="font-size:10px;color:var(--muted);">${svcInstances[0].instanceUid.slice(0,8)}...</span>`:'';
return `<div class="${cls}">${btn} ${o.operation} ${hint} ${instUid}</div>`;
}).join('');
let html='';
// Инстансы с именами и статусами
if(svcInstances.length>0){
html+='<div style="font-size:11px;font-weight:600;padding:4px 8px;color:var(--muted);">Инстансы</div>';
svcInstances.forEach(i=>{
const sc=i.explainedStatus==='running'?'badge-success':'';
html+=`<div class="op-item" style="cursor:pointer;" onclick="selectInstance('${i.instanceUid}')" data-iuid="${i.instanceUid}">
<span style="flex:1;font-size:12px;">${i.displayName}</span>
<span class="badge ${sc}" style="font-size:9px;">${i.explainedStatus||'?'}</span>
</div>`;
});
}
// Операции
html+='<div style="font-size:11px;font-weight:600;padding:4px 8px;color:var(--muted);margin-top:4px;">Операции</div>';
d.operations.filter(o=>o.operation!=='reconcile').forEach(o=>{
const isCreate=o.operation==='create';
const disabled=!isCreate&&!selectedInst;
const btn=disabled?'':`<button class="btn btn-primary btn-sm" onclick="selectOperation(${o.svcOperationId},'${o.operation}',${svcId})">Тест</button>`;
const hint=isCreate&&svcInstances.length>0?'<span style="font-size:10px;color:var(--muted);">уже есть</span>':
(!isCreate&&!selectedInst?'<span style="font-size:10px;color:var(--muted);">выберите инстанс</span>':'');
html+=`<div class="op-item${disabled?' disabled':''}" id="op-${o.operation}">${btn} ${o.operation} ${hint}</div>`;
});
document.getElementById('ops-list').innerHTML=html;
}
function selectInstance(iuid){
selectedInst=iuid;
document.querySelectorAll('[data-iuid]').forEach(e=>e.classList.toggle('active',e.dataset.iuid===iuid));
document.querySelectorAll('#ops-list .op-item').forEach(e=>{
if(e.id!=='op-create') e.classList.remove('disabled');
});
document.querySelectorAll('#op-create').forEach(e=>e.classList.add('disabled'));
}
async function selectOperation(opId,opName,svcId){
@@ -181,10 +198,8 @@ async function runTest(){
params[el.name.replace('p_','')]=v;
});
let instUid='';
if(selectedOp.opName!=='create'&&svcInstances.length>0){
instUid=svcInstances[0].instanceUid;
}
let instUid=selectedInst||'';
if(selectedOp.opName==='create') instUid='';
try{
const r=await fetch('/api/test',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({