diff --git a/web/templates/configs.html b/web/templates/configs.html index f655ec7..6aba590 100644 --- a/web/templates/configs.html +++ b/web/templates/configs.html @@ -63,10 +63,16 @@
- + + +
+ +
@@ -171,10 +177,10 @@ @@ -190,6 +196,8 @@ let projectsCache = []; let projectNameByUUID = {}; let pendingMoveConfigUUID = ''; let pendingMoveProjectName = ''; +let pendingCreateConfigName = ''; +let pendingCreateProjectName = ''; function renderConfigs(configs) { const emptyText = configStatusMode === 'archived' @@ -407,6 +415,7 @@ async function cloneConfig() { function openCreateModal() { document.getElementById('opportunity-number').value = ''; + document.getElementById('create-project-input').value = ''; document.getElementById('create-modal').classList.remove('hidden'); document.getElementById('create-modal').classList.add('flex'); document.getElementById('opportunity-number').focus(); @@ -425,8 +434,25 @@ async function createConfig() { return; } - const projectUUID = document.getElementById('create-project-select').value; + const projectName = document.getElementById('create-project-input').value.trim(); + let projectUUID = ''; + if (projectName) { + const existingProject = projectsCache.find(p => p.is_active && p.name.toLowerCase() === projectName.toLowerCase()); + if (existingProject) { + projectUUID = existingProject.uuid; + } else { + pendingCreateConfigName = name; + pendingCreateProjectName = projectName; + openCreateProjectOnCreateModal(projectName); + return; + } + } + + await createConfigWithProject(name, projectUUID); +} + +async function createConfigWithProject(name, projectUUID) { try { const resp = await fetch('/api/configs', { method: 'POST', @@ -442,16 +468,17 @@ async function createConfig() { }) }); + const config = await resp.json(); if (!resp.ok) { - const err = await resp.json(); - alert('Ошибка: ' + (err.error || 'Не удалось создать')); - return; + alert('Ошибка: ' + (config.error || 'Не удалось создать')); + return false; } - const config = await resp.json(); window.location.href = '/configurator?uuid=' + config.uuid; + return true; } catch(e) { alert('Ошибка создания конфигурации'); + return false; } } @@ -510,8 +537,22 @@ function clearMoveProjectInput() { document.getElementById('move-project-input').value = ''; } +function clearCreateProjectInput() { + document.getElementById('create-project-input').value = ''; +} + function openCreateProjectOnMoveModal(projectName) { document.getElementById('create-project-on-move-name').textContent = projectName; + document.getElementById('create-project-on-move-description').textContent = 'Создать и привязать квоту?'; + document.getElementById('create-project-on-move-confirm-btn').textContent = 'Создать и привязать'; + document.getElementById('create-project-on-move-modal').classList.remove('hidden'); + document.getElementById('create-project-on-move-modal').classList.add('flex'); +} + +function openCreateProjectOnCreateModal(projectName) { + document.getElementById('create-project-on-move-name').textContent = projectName; + document.getElementById('create-project-on-move-description').textContent = 'Создать и использовать для новой конфигурации?'; + document.getElementById('create-project-on-move-confirm-btn').textContent = 'Создать и использовать'; document.getElementById('create-project-on-move-modal').classList.remove('hidden'); document.getElementById('create-project-on-move-modal').classList.add('flex'); } @@ -521,9 +562,43 @@ function closeCreateProjectOnMoveModal() { document.getElementById('create-project-on-move-modal').classList.remove('flex'); pendingMoveConfigUUID = ''; pendingMoveProjectName = ''; + pendingCreateConfigName = ''; + pendingCreateProjectName = ''; } async function confirmCreateProjectOnMove() { + if (pendingCreateConfigName && pendingCreateProjectName) { + const configName = pendingCreateConfigName; + const projectName = pendingCreateProjectName; + try { + const createResp = await fetch('/api/projects', { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({ name: projectName }) + }); + if (!createResp.ok) { + const err = await createResp.json(); + alert('Не удалось создать проект: ' + (err.error || 'ошибка')); + return; + } + + const newProject = await createResp.json(); + pendingCreateConfigName = ''; + pendingCreateProjectName = ''; + await loadProjectsForConfigUI(); + const created = await createConfigWithProject(configName, newProject.uuid); + if (created) { + closeCreateProjectOnMoveModal(); + } else { + closeCreateProjectOnMoveModal(); + document.getElementById('create-project-input').value = projectName; + } + } catch (e) { + alert('Ошибка создания проекта'); + } + return; + } + const configUUID = pendingMoveConfigUUID; const projectName = pendingMoveProjectName; if (!configUUID || !projectName) { @@ -544,10 +619,15 @@ async function confirmCreateProjectOnMove() { } const newProject = await createResp.json(); + pendingMoveConfigUUID = ''; + pendingMoveProjectName = ''; + await loadProjectsForConfigUI(); + document.getElementById('move-project-input').value = projectName; const moved = await moveConfigToProject(configUUID, newProject.uuid); if (moved) { closeCreateProjectOnMoveModal(); - closeMoveProjectModal(); + } else { + closeCreateProjectOnMoveModal(); } } catch (e) { alert('Ошибка создания проекта'); @@ -760,16 +840,18 @@ async function loadProjectsForConfigUI() { const data = await resp.json(); projectsCache = (data.projects || []); - const select = document.getElementById('create-project-select'); - if (select) { - select.innerHTML = ''; + projectsCache.forEach(project => { + projectNameByUUID[project.uuid] = project.name; + }); + + const createOptions = document.getElementById('create-project-options'); + if (createOptions) { + createOptions.innerHTML = ''; projectsCache.forEach(project => { - projectNameByUUID[project.uuid] = project.name; if (!project.is_active) return; const option = document.createElement('option'); - option.value = project.uuid; - option.textContent = project.name; - select.appendChild(option); + option.value = project.name; + createOptions.appendChild(option); }); } } catch (e) {