- scenario-form.js: fix ReferenceError body is not defined in renderEditor() - utils.js: relativeTime(iso) → 3ч 12м / 2д 5ч / только что - instances.js: columns created / modified with relativeTime() - index.html: instanceUid under displayName in infra column
91 lines
4.2 KiB
JavaScript
91 lines
4.2 KiB
JavaScript
// instances.js — список инстансов, выбор сервиса, toggle операций
|
|
|
|
let svcInstances=[], selectedInst=null, selectedOp=null;
|
|
let currentSvcId=(window.APP&&window.APP.firstServiceId)||1;
|
|
let currentSvcName='';
|
|
let currentSvcShort='';
|
|
let busy=false;
|
|
const AUTOTEST_PREFIX='autotest-';
|
|
|
|
async function selectService(svcId){
|
|
if(busy) return;
|
|
currentSvcId=svcId;
|
|
selectedInst=null; selectedOp=null; stopPoll();
|
|
document.getElementById('params-area').style.display='none';
|
|
document.querySelectorAll('.stages-box').forEach(e=>e.remove());
|
|
document.querySelectorAll('.svc-item').forEach(e=>e.classList.remove('active'));
|
|
const svcEl=document.querySelector(`.svc-item[onclick*="${svcId}"]`);
|
|
if(svcEl) svcEl.classList.add('active');
|
|
try{
|
|
const r=await fetch('/api/operations/'+svcId);
|
|
const d=await r.json();
|
|
svcInstances=d.instances||[];
|
|
currentSvcName=d.svc||'';
|
|
currentSvcShort=d.svcShort||'';
|
|
const btnSpan=document.querySelector('#create-btn-area span');
|
|
if(btnSpan) btnSpan.textContent='+ Создать новый инстанс '+(currentSvcName||'сервиса');
|
|
renderInstances();
|
|
}catch(e){document.getElementById('inst-list').innerHTML='<span style="color:var(--destructive);font-size:11px;">Ошибка загрузки</span>';}
|
|
}
|
|
|
|
function renderInstances(){
|
|
let html='';
|
|
svcInstances.forEach(i=>{
|
|
const status=i.status||i.explainedStatus||'?';
|
|
const sc=status==='running'?'badge-success':'';
|
|
html+=`<div class="inst-item" onclick="toggleInstance('${i.instanceUid}')" data-iuid="${i.instanceUid}">
|
|
<span style="display:inline-block;width:220px;">${_esc(i.displayName)}</span>
|
|
<span style="display:inline-block;width:140px;color:var(--muted);font-size:11px;">${_esc(i.svc||'')}</span>
|
|
<span class="badge ${sc}" style="font-size:9px;">${_esc(status)}</span>
|
|
<span style="display:inline-block;width:60px;color:var(--muted);font-size:9px;text-align:right;" title="${i.instanceConfigDtCreated||''}">${relativeTime(i.instanceConfigDtCreated)}</span>
|
|
<span style="display:inline-block;width:60px;color:var(--muted);font-size:9px;text-align:right;" title="${i.instanceConfigDtModified||''}">${relativeTime(i.instanceConfigDtModified)}</span>
|
|
</div>`;
|
|
html+=`<div class="inst-ops" id="ops-${i.instanceUid}"></div>`;
|
|
});
|
|
document.getElementById('inst-list').innerHTML=html;
|
|
}
|
|
|
|
async function refreshInstances(){
|
|
try{
|
|
const r=await fetch('/api/operations/'+currentSvcId);
|
|
const d=await r.json();
|
|
svcInstances=d.instances||[];
|
|
renderInstances();
|
|
}catch(e){}
|
|
}
|
|
|
|
async function toggleInstance(iuid){
|
|
if(busy) return;
|
|
selectedInst=iuid; stopPoll();
|
|
document.querySelectorAll('[data-iuid]').forEach(e=>e.classList.toggle('active',e.dataset.iuid===iuid));
|
|
document.getElementById('params-area').style.display='none';
|
|
const opsEl=document.getElementById('ops-'+iuid);
|
|
if(opsEl.classList.contains('open')){opsEl.classList.remove('open');return;}
|
|
document.querySelectorAll('.inst-ops').forEach(e=>e.classList.remove('open'));
|
|
const inst=svcInstances.find(x=>x.instanceUid===iuid);
|
|
const svcId=inst?inst.serviceId:currentSvcId;
|
|
try{
|
|
const r=await fetch('/api/operations/'+svcId);
|
|
const d=await r.json();
|
|
let ops=(d.operations||[]).filter(o=>o.operation!=='reconcile'&&o.operation!=='create');
|
|
if(inst&&(inst.status||inst.explainedStatus)==='not created'){
|
|
ops=ops.filter(o=>o.operation==='delete');
|
|
}
|
|
opsEl.innerHTML=ops.map(o=>
|
|
`<button class="btn btn-sm op-btn ${opClass(o.operation)}" onclick="runOp('${o.operation}',${o.svcOperationId})">${o.operation}</button>`
|
|
).join('');
|
|
opsEl.classList.add('open');
|
|
}catch(e){opsEl.innerHTML='<span style="color:var(--destructive);font-size:11px;">Ошибка загрузки</span>';opsEl.classList.add('open');}
|
|
}
|
|
|
|
function opClass(opName){
|
|
if(opName==='modify') return 'op-btn-modify';
|
|
if(opName==='suspend') return 'op-btn-suspend';
|
|
if(opName==='resume') return 'op-btn-resume';
|
|
if(opName==='delete') return 'op-btn-delete';
|
|
if(opName==='redeploy') return 'op-btn-redeploy';
|
|
return '';
|
|
}
|
|
|
|
|