v1.2.11: scenario list — expandable steps + run confirmation
- Click on scenario name → expands to show step details:
operation → service_id (output/ref/uid) (params)
- ▶ Запустить button inside expanded view
- confirm('Запустить сценарий?') before running
- CRUD buttons (✏📋🗑) with event.stopPropagation()
- toggleScenarioSteps(defId): single-expand (closes others)
This commit is contained in:
@@ -23,13 +23,17 @@ async function loadScenarios(){
|
||||
html+='<div style="display:flex;flex-direction:column;gap:4px;margin-bottom:4px;">';
|
||||
sr.forEach(s=>{
|
||||
const seed = s.is_seed;
|
||||
html+=`<div style="display:flex;align-items:center;gap:4px;">`;
|
||||
html+=`<button class="btn btn-sm" style="font-size:12px;flex:1;text-align:left;" onclick="runScenario(${s.id})" title="Запустить">▶ ${_esc(s.name)} <span style="color:var(--muted);">(${s.steps} шагов)</span></button>`;
|
||||
if(!seed) html+=`<button class="btn btn-sm" style="font-size:13px;padding:0 6px;" onclick="editScenario(${s.id})" title="Редактировать">✏</button>`;
|
||||
html+=`<button class="btn btn-sm" style="font-size:13px;padding:0 6px;" onclick="cloneScenario(${s.id},'${_esc(s.name)}')" title="Копировать">📋</button>`;
|
||||
if(!seed) html+=`<button class="btn btn-sm" style="font-size:13px;padding:0 6px;color:var(--destructive);" onclick="deleteScenario(${s.id},'${_esc(s.name)}')" title="Удалить">🗑</button>`;
|
||||
html+=`<div style="border:1px solid var(--brand-gray);border-radius:4px;padding:4px 6px;">`;
|
||||
html+=`<div style="display:flex;align-items:center;gap:4px;cursor:pointer;" onclick="toggleScenarioSteps(${s.id})">`;
|
||||
html+=`<span style="font-size:13px;font-weight:600;flex:1;">${_esc(s.name)}</span>`;
|
||||
html+=`<span style="color:var(--muted);font-size:11px;">${s.steps} шагов</span>`;
|
||||
if(!seed) html+=`<button class="btn btn-sm" style="font-size:12px;padding:0 6px;" onclick="event.stopPropagation();editScenario(${s.id})" title="Редактировать">✏</button>`;
|
||||
html+=`<button class="btn btn-sm" style="font-size:12px;padding:0 6px;" onclick="event.stopPropagation();cloneScenario(${s.id},'${_esc(s.name)}')" title="Копировать">📋</button>`;
|
||||
if(!seed) html+=`<button class="btn btn-sm" style="font-size:12px;padding:0 6px;color:var(--destructive);" onclick="event.stopPropagation();deleteScenario(${s.id},'${_esc(s.name)}')" title="Удалить">🗑</button>`;
|
||||
if(seed) html+=`<span style="font-size:9px;color:var(--muted);padding:0 4px;">seed</span>`;
|
||||
html+=`</div>`;
|
||||
html+=`<div id="scenario-steps-${s.id}" style="display:none;margin-top:4px;padding-left:8px;"></div>`;
|
||||
html+=`</div>`;
|
||||
});
|
||||
html+='</div>';
|
||||
}else{
|
||||
@@ -49,8 +53,39 @@ async function loadScenarios(){
|
||||
}catch(e){body.innerHTML='<span style="color:var(--destructive);font-size:11px;">Ошибка загрузки</span>';}
|
||||
}
|
||||
|
||||
async function toggleScenarioSteps(defId) {
|
||||
const el = document.getElementById('scenario-steps-' + defId);
|
||||
if (!el) return;
|
||||
if (el.style.display === 'block') { el.style.display = 'none'; return; }
|
||||
// Загрузить шаги
|
||||
try {
|
||||
const r = await fetch('/api/scenario/definitions/' + defId);
|
||||
const def = await r.json();
|
||||
if (def.error) return;
|
||||
const steps = def.steps || [];
|
||||
let html = '<div style="font-size:11px;padding:4px 0;">';
|
||||
steps.forEach((s, i) => {
|
||||
const svcName = s.service_id ? 'сервис ' + s.service_id : '?';
|
||||
html += `<div style="padding:2px 0;">${i+1}. <b>${_esc(s.operation)}</b> → ${svcName}`;
|
||||
if (s.output) html += ` <span style="color:var(--muted);">(${_esc(s.output)})</span>`;
|
||||
if (s.instance_ref) html += ` <span style="color:var(--muted);">→ ${_esc(s.instance_ref)}</span>`;
|
||||
if (s.instance_uid) html += ` <span style="color:var(--muted);">→ ${_esc(s.instance_uid.substring(0,8))}...</span>`;
|
||||
const params = Object.entries(s.params || {});
|
||||
if (params.length) html += ' <span style="color:var(--muted);">(' + params.map(([k,v]) => k+'='+v).join(', ') + ')</span>';
|
||||
html += '</div>';
|
||||
});
|
||||
html += `<button class="btn btn-sm" style="margin-top:4px;font-size:11px;background:var(--brand-primary);color:#fff;" onclick="event.stopPropagation();runScenario(${defId})">▶ Запустить</button>`;
|
||||
html += '</div>';
|
||||
el.innerHTML = html;
|
||||
el.style.display = 'block';
|
||||
// Закрыть другие
|
||||
document.querySelectorAll('[id^="scenario-steps-"]').forEach(e => { if (e !== el) e.style.display = 'none'; });
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
async function runScenario(defId){
|
||||
if(busy){ return; }
|
||||
if(!confirm('Запустить сценарий?')) return;
|
||||
busy=true;
|
||||
stopScenarioPoll();
|
||||
const body=document.getElementById('scenario-body');
|
||||
|
||||
Reference in New Issue
Block a user