// CRUD-операции с функциями (создание, редактирование, удаление) function onLangChange() { var lang = document.getElementById('c-lang').value; var t = LANG_TEMPLATES[lang]; if (t) { document.getElementById('c-entry').value = t.entrypoint; document.getElementById('c-code').value = t.code; } } function openCreate() { document.getElementById('c-lang').value = 'python'; onLangChange(); document.getElementById('c-timeout').value = '60'; document.getElementById('c-schedule-enabled').checked = false; document.getElementById('c-cron').value = ''; toggleScheduleFields('c'); document.getElementById('create-modal').classList.add('open'); document.getElementById('c-name').focus(); } function closeCreate() { document.getElementById('create-modal').classList.remove('open'); } async function submitCreate() { const btn = document.getElementById('c-submit'); btn.disabled = true; const progress = startTimedStatus('Создаём функцию...', 'Создание функции...', explainDelay); try { const name = document.getElementById('c-name').value.trim(); if (!name) throw new Error('name is required'); const lang = document.getElementById('c-lang').value.trim(); if (!lang) throw new Error('language is required'); await requestJSON(API_BASE + '/functions', 'POST', { name: name, language: lang, entrypoint: document.getElementById('c-entry').value.trim(), route: document.getElementById('c-route').value.trim(), methods: parseMethods(document.getElementById('c-methods').value), timeout: parseTimeout(document.getElementById('c-timeout').value), code: document.getElementById('c-code').value }); try { await syncScheduleForFunction(name, 'c'); } catch (scheduleErr) { try { await requestJSON(API_BASE + '/functions/' + encodeURIComponent(name), 'DELETE'); } catch (rollbackErr) { scheduleErr.message += '; rollback failed: ' + rollbackErr.message; } throw scheduleErr; } closeCreate(); progress.stop('\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0430: ' + name, 'ok'); await reloadAll(); } catch (e) { progress.stop('\u041e\u0448\u0438\u0431\u043a\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f: ' + e.message, 'err'); } finally { btn.disabled = false; } }