152 lines
6.1 KiB
JavaScript
152 lines
6.1 KiB
JavaScript
// Модальные окна
|
||
|
||
async function openEdit(name) {
|
||
try {
|
||
const fn = await getJSON(API_BASE + '/functions/' + encodeURIComponent(name));
|
||
S.currentEdit = fn;
|
||
document.getElementById('e-title').textContent = 'Редактирование: ' + name;
|
||
document.getElementById('e-name').value = name;
|
||
document.getElementById('e-env').value = fn.environment || '';
|
||
document.getElementById('e-entry').value = fn.entrypoint || '';
|
||
document.getElementById('e-timeout').value = String(fn.timeout || 60);
|
||
document.getElementById('e-code').value = fn.code || '';
|
||
var schedule = timeTriggerByFn(name);
|
||
document.getElementById('e-schedule-enabled').checked = !!schedule;
|
||
document.getElementById('e-cron').value = (schedule && schedule.spec && schedule.spec.cron) || '';
|
||
toggleScheduleFields('e');
|
||
var envName = (fn.environment || '').toLowerCase();
|
||
var lang = 'python';
|
||
if (envName.includes('node')) lang = 'nodejs';
|
||
else if (envName.includes('go')) lang = 'go';
|
||
else if (envName.includes('ruby')) lang = 'ruby';
|
||
else if (envName.includes('php')) lang = 'php';
|
||
document.getElementById('e-lang-hidden').value = lang;
|
||
var aiRes = document.getElementById('e-ai-result');
|
||
if (aiRes) { aiRes.style.display = 'none'; aiRes.textContent = ''; }
|
||
var warnEl = document.getElementById('e-tf-warn');
|
||
if (warnEl) {
|
||
var isTf = /^tf-/.test(name) || /go[-_]env/.test(fn.environment || '');
|
||
warnEl.style.display = isTf ? 'block' : 'none';
|
||
}
|
||
document.getElementById('edit-modal').classList.add('open');
|
||
} catch (e) {
|
||
showStatus('Ошибка загрузки функции: ' + e.message, 'err');
|
||
}
|
||
}
|
||
|
||
function closeEdit() {
|
||
document.getElementById('edit-modal').classList.remove('open');
|
||
S.currentEdit = null;
|
||
}
|
||
|
||
function openHelp() {
|
||
document.getElementById('help-modal').classList.add('open');
|
||
}
|
||
|
||
function closeHelp() {
|
||
document.getElementById('help-modal').classList.remove('open');
|
||
}
|
||
|
||
async function submitEdit() {
|
||
if (!S.currentEdit) return;
|
||
const btn = document.getElementById('e-submit');
|
||
btn.disabled = true;
|
||
const progress = startTimedStatus('Сохраняем код...', 'Сохранение кода...', explainDelay);
|
||
try {
|
||
const name = S.currentEdit.name;
|
||
await requestJSON(API_BASE + '/functions/' + encodeURIComponent(name) + '/code', 'PUT', {
|
||
code: document.getElementById('e-code').value,
|
||
timeout: parseTimeout(document.getElementById('e-timeout').value)
|
||
});
|
||
|
||
await syncScheduleForFunction(name, 'e');
|
||
closeEdit();
|
||
progress.stop('Код обновлён: ' + name, 'ok');
|
||
await reloadAll();
|
||
} catch (e) {
|
||
progress.stop('Ошибка обновления: ' + e.message, 'err');
|
||
} finally {
|
||
btn.disabled = false;
|
||
}
|
||
}
|
||
|
||
function openInvoke(name) {
|
||
S.currentInvoke = name;
|
||
document.getElementById('i-title').textContent = 'Вызов: ' + name;
|
||
document.getElementById('i-resp').value = '';
|
||
document.getElementById('i-status').textContent = '';
|
||
document.getElementById('i-meta').style.display = 'none';
|
||
document.getElementById('i-meta').textContent = '';
|
||
document.getElementById('invoke-modal').classList.add('open');
|
||
}
|
||
|
||
function closeInvoke() {
|
||
document.getElementById('invoke-modal').classList.remove('open');
|
||
S.currentInvoke = null;
|
||
}
|
||
|
||
async function submitInvoke() {
|
||
if (!S.currentInvoke) return;
|
||
const btn = document.getElementById('i-submit');
|
||
const statusEl = document.getElementById('i-status');
|
||
const metaEl = document.getElementById('i-meta');
|
||
const respEl = document.getElementById('i-resp');
|
||
btn.disabled = true;
|
||
respEl.value = '';
|
||
metaEl.style.display = 'none';
|
||
metaEl.textContent = '';
|
||
let elapsed = 0;
|
||
statusEl.textContent = 'Вызов...';
|
||
const timer = setInterval(() => {
|
||
elapsed++;
|
||
if (elapsed < 5) {
|
||
statusEl.textContent = 'Вызов... ' + elapsed + 'с';
|
||
} else if (elapsed < 10) {
|
||
statusEl.textContent = '⏳ Возможен cold start — прогрев пула... ' + elapsed + 'с';
|
||
} else {
|
||
statusEl.textContent = '⏳ Возможны cold start или specialization... ' + elapsed + 'с';
|
||
}
|
||
}, 1000);
|
||
try {
|
||
const raw = document.getElementById('i-body').value.trim();
|
||
let parsed = {};
|
||
if (raw) parsed = JSON.parse(raw);
|
||
const result = await requestJSON(API_BASE + '/functions/' + encodeURIComponent(S.currentInvoke) + '/invoke', 'POST', parsed);
|
||
var latencyMs = Number(result.latency_ms || 0);
|
||
var measuredSeconds = latencyMs > 0 ? Math.max(1, Math.round(latencyMs / 1000)) : elapsed;
|
||
statusEl.textContent = '✓ Выполнено за ' + formatSeconds(measuredSeconds);
|
||
metaEl.style.display = 'block';
|
||
metaEl.textContent = [
|
||
'HTTP status: ' + (result.status || 'n/a'),
|
||
'Latency: ' + (latencyMs || 'n/a') + ' ms',
|
||
'Причина задержки: ' + explainDelay(measuredSeconds),
|
||
'Invoke URL: ' + (result.invoke_url || 'n/a')
|
||
].join('\n');
|
||
respEl.value = JSON.stringify(result, null, 2);
|
||
} catch (e) {
|
||
statusEl.textContent = '✗ Ошибка после ' + formatSeconds(elapsed);
|
||
metaEl.style.display = 'block';
|
||
metaEl.textContent = [
|
||
'Последняя ошибка: ' + e.message,
|
||
'Вероятная причина задержки: ' + explainDelay(elapsed)
|
||
].join('\n');
|
||
respEl.value = 'Ошибка вызова: ' + e.message;
|
||
} finally {
|
||
clearInterval(timer);
|
||
btn.disabled = false;
|
||
}
|
||
}
|
||
|
||
async function removeFn(name) {
|
||
var tfWarn = (/^tf-/.test(name)) ? '\n\n⚠️ Эта функция управляется Terraform. Удаление приведёт к рассинхронизации state!' : '';
|
||
if (!confirm('Удалить функцию ' + name + '?' + tfWarn)) return;
|
||
var progress = startTimedStatus('Удаляем функцию...', 'Удаление функции...', explainDelay);
|
||
try {
|
||
await requestJSON(API_BASE + '/functions/' + encodeURIComponent(name), 'DELETE');
|
||
progress.stop('Функция удалена: ' + name, 'ok');
|
||
await reloadAll();
|
||
} catch (e) {
|
||
progress.stop('Ошибка удаления: ' + e.message, 'err');
|
||
}
|
||
}
|