// scenario-form.js — общий редактор шагов сценария (create + edit)
let scenarioEditorState = null; // {defId, version, name, steps:[]}
// steps: [{service_id, operation, params: [["key","val"],...]}]
function showScenarioEditor(def) {
const body = document.getElementById('scenario-body');
scenarioEditorState = def ? {
defId: def.id, version: def.version, name: def.name,
steps: (def.steps || []).map(s => ({
service_id: s.service_id, operation: s.operation,
params: Object.entries(s.params || {})
}))
} : { defId: null, version: 1, name: '', steps: [] };
renderEditor();
}
function renderEditor() {
const body = document.getElementById('scenario-body');
const st = scenarioEditorState;
let html = '
';
html += '
';
html += ``;
html += '
';
html += '
Шаги:
';
st.steps.forEach((s, idx) => {
html += renderStepRow(idx, s);
});
html += `
`;
html += '
';
html += ` `;
html += '';
html += '
';
body.innerHTML = html;
}
function renderStepRow(idx, step) {
const svcId = step.service_id || '';
const op = step.operation || '';
const params = step.params || [];
let html = `';
return html;
}
function addStep() {
scenarioEditorState.steps.push({ service_id: 1, operation: 'create', params: [] });
renderEditor();
}
function removeStep(idx) {
scenarioEditorState.steps.splice(idx, 1);
renderEditor();
}
function addParam(idx) {
scenarioEditorState.steps[idx].params.push(['', '']);
}
function removeParam(idx, pi) {
scenarioEditorState.steps[idx].params.splice(pi, 1);
}
function onStepChange(idx) { /* placeholder for future auto-load */ }
function collectFormSteps() {
const st = scenarioEditorState;
const name = (document.getElementById('scenario-name')?.value || '').trim();
const steps = [];
st.steps.forEach((_, idx) => {
const svcEl = document.getElementById(`step-${idx}-svc`);
const opEl = document.getElementById(`step-${idx}-op`);
const svcId = parseInt(svcEl?.value) || 0;
const operation = (opEl?.value || '').trim();
const params = {};
st.steps[idx].params.forEach((__, pi) => {
const k = document.getElementById(`step-${idx}-pk-${pi}`)?.value?.trim();
const v = document.getElementById(`step-${idx}-pv-${pi}`)?.value || '';
if (k) params[k] = v;
});
steps.push({ service_id: svcId, operation, params });
});
return { name, steps };
}
async function saveScenario() {
const { name, steps } = collectFormSteps();
if (!name) { alert('Введите название'); return; }
if (!steps.length) { alert('Добавьте хотя бы один шаг'); return; }
for (let i = 0; i < steps.length; i++) {
if (!steps[i].service_id) { alert('Шаг ' + (i+1) + ': укажите service_id'); return; }
if (!steps[i].operation) { alert('Шаг ' + (i+1) + ': укажите operation'); return; }
}
const st = scenarioEditorState;
const isNew = !st.defId;
const url = isNew ? '/api/scenario/definitions' : '/api/scenario/definitions/' + st.defId;
const method = isNew ? 'POST' : 'PUT';
const body = isNew ? { name, steps } : { name, steps, version: st.version };
try {
const r = await fetch(url, { method, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) });
const d = await r.json();
if (r.status === 409) {
alert('⚠️ Конфликт версий — кто-то уже изменил сценарий. Обновите страницу.');
return;
}
if (d.error) { alert(d.error); return; }
if (isNew && d.id) st.defId = d.id;
if (d.version) st.version = d.version;
await loadScenarios();
} catch (e) {
alert('Ошибка сохранения: ' + e.message);
}
}