refactor(settings): AI profile add/edit moved into a modal dialog (overlay click + Esc to close)

This commit is contained in:
dev
2026-09-17 12:00:19 +03:00
parent d7c793c67a
commit 66f7fdc1a8
2 changed files with 40 additions and 31 deletions
+11 -3
View File
@@ -180,7 +180,8 @@ let aiProfileEditingId = null;
function openAiProfileForm(profile) {
aiProfileEditingId = profile ? profile.id : null;
document.getElementById('aiProfileForm').style.display = 'block';
document.getElementById('aiProfileModalTitle').textContent = profile ? 'Изменить профиль ИИ' : 'Добавить профиль ИИ';
document.getElementById('aiProfileModal').classList.add('open');
document.getElementById('aiProfileName').value = profile ? profile.name : '';
document.getElementById('aiProfileModel').value = profile ? profile.model : '';
document.getElementById('aiProfileBaseUrl').value = profile ? profile.base_url : '';
@@ -191,7 +192,7 @@ function openAiProfileForm(profile) {
function closeAiProfileForm() {
aiProfileEditingId = null;
document.getElementById('aiProfileForm').style.display = 'none';
document.getElementById('aiProfileModal').classList.remove('open');
}
function aiProfileFormData() {
@@ -218,18 +219,21 @@ async function loadAiQueue() {
async function saveAiProfile() {
const body = aiProfileFormData();
const st = document.getElementById('aiProfileTestStatus');
st.innerHTML = '<span class="spinner dark"></span> Сохранение...';
const res = await fetch(aiProfileEditingId ? `${API}/api/ai/profiles/${aiProfileEditingId}` : `${API}/api/ai/profiles`, {
method: aiProfileEditingId ? 'PUT' : 'POST',
headers: hdrJson(),
body: JSON.stringify(body),
});
if (res.ok) {
st.textContent = '';
showToast(aiProfileEditingId ? 'Профиль обновлён' : 'Профиль добавлен');
closeAiProfileForm();
loadAiProfiles();
} else {
const err = await res.json().catch(() => ({}));
alert(err.error || 'Ошибка сохранения');
st.innerHTML = `<span style="color:#ef4444;font-weight:600">${esc(err.error || 'Ошибка сохранения')}</span>`;
}
}
@@ -271,6 +275,10 @@ document.getElementById('aiProfileAddBtn').addEventListener('click', () => openA
document.getElementById('aiProfileSaveBtn').addEventListener('click', saveAiProfile);
document.getElementById('aiProfileTestBtn').addEventListener('click', testAiProfile);
document.getElementById('aiProfileCancelBtn').addEventListener('click', closeAiProfileForm);
document.getElementById('aiProfileModal').addEventListener('click', e => { if (e.target === e.currentTarget) closeAiProfileForm(); });
document.addEventListener('keydown', e => {
if (e.key === 'Escape' && document.getElementById('aiProfileModal').classList.contains('open')) closeAiProfileForm();
});
document.getElementById('aiActiveProfile').addEventListener('change', e => activateAiProfile(e.target.value));
document.getElementById('aiProfilesList').addEventListener('click', e => {
const del = e.target.closest('[data-del-profile]');