313 lines
8.9 KiB
JavaScript
313 lines
8.9 KiB
JavaScript
/**
|
||
* Settings UI
|
||
*
|
||
* UI компонент для диалога настроек.
|
||
*/
|
||
|
||
import appState from '../state/appState.js'
|
||
import settingsService from '../services/settings.service.js'
|
||
import { defaultSettings } from '../data/defaults.js'
|
||
import { downloadJSON, loadFileAsJSON } from '../utils/file.utils.js'
|
||
import { showToast, getInputValue, setInputValue, addClass, removeClass, showElement, hideElement } from '../utils/dom.utils.js'
|
||
|
||
/**
|
||
* Открыть диалог настроек
|
||
*/
|
||
export function open() {
|
||
populate()
|
||
const dialog = document.getElementById('settings-dialog')
|
||
if (dialog) {
|
||
addClass(dialog, 'open')
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Закрыть диалог настроек
|
||
*/
|
||
export function close() {
|
||
const dialog = document.getElementById('settings-dialog')
|
||
if (dialog) {
|
||
removeClass(dialog, 'open')
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Заполнить диалог настроек текущими значениями
|
||
*/
|
||
export function populate() {
|
||
const env = appState.getCurrentEnvironment()
|
||
const envSettings = appState.getCurrentEnvSettings()
|
||
|
||
if (!envSettings) {
|
||
console.error('Environment settings not found')
|
||
return
|
||
}
|
||
|
||
// Set environment selector
|
||
const envSelector = document.getElementById('settings-env-selector')
|
||
if (envSelector) {
|
||
envSelector.value = env
|
||
}
|
||
|
||
// API Mode
|
||
const apiMode = envSettings.apiMode || 'bench'
|
||
const apiModeSelect = document.getElementById('setting-api-mode')
|
||
if (apiModeSelect) {
|
||
apiModeSelect.value = apiMode
|
||
}
|
||
|
||
toggleBackendSettings(apiMode === 'backend')
|
||
|
||
// Populate environment-specific fields (только редактируемые пользователем)
|
||
setInputValue('setting-bearer-token', envSettings.bearerToken || '')
|
||
setInputValue('setting-system-platform', envSettings.systemPlatform || '')
|
||
setInputValue('setting-system-platform-user', envSettings.systemPlatformUser || '')
|
||
|
||
// Backend mode fields
|
||
setInputValue('setting-platform-user-id', envSettings.platformUserId || '')
|
||
setInputValue('setting-platform-id', envSettings.platformId || '')
|
||
|
||
const classifyCheckbox = document.getElementById('setting-with-classify')
|
||
if (classifyCheckbox) {
|
||
classifyCheckbox.checked = envSettings.withClassify || false
|
||
}
|
||
|
||
const resetSessionCheckbox = document.getElementById('setting-reset-session-mode')
|
||
if (resetSessionCheckbox) {
|
||
resetSessionCheckbox.checked = envSettings.resetSessionMode !== false
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Показать/скрыть backend настройки
|
||
* @param {boolean} show - Показать или скрыть
|
||
*/
|
||
export function toggleBackendSettings(show) {
|
||
const backendSettings = document.getElementById('backend-settings')
|
||
const backendHeader = document.getElementById('backend-settings-header')
|
||
|
||
if (show) {
|
||
showElement(backendSettings)
|
||
showElement(backendHeader)
|
||
} else {
|
||
hideElement(backendSettings)
|
||
hideElement(backendHeader)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Прочитать настройки из диалога
|
||
* @returns {object} Обновлённые настройки
|
||
*/
|
||
export function read() {
|
||
const envSelector = document.getElementById('settings-env-selector')
|
||
if (!envSelector) {
|
||
console.error('Settings env selector not found')
|
||
return null
|
||
}
|
||
|
||
const env = envSelector.value
|
||
|
||
// Update environment-specific settings
|
||
const updatedSettings = JSON.parse(JSON.stringify(appState.settings)) // Deep copy
|
||
|
||
if (!updatedSettings.environments[env]) {
|
||
console.error(`Environment ${env} not found in settings`)
|
||
return null
|
||
}
|
||
|
||
updatedSettings.environments[env] = {
|
||
name: updatedSettings.environments[env].name,
|
||
apiMode: getInputValue('setting-api-mode'),
|
||
bearerToken: getInputValue('setting-bearer-token').trim(),
|
||
systemPlatform: getInputValue('setting-system-platform').trim(),
|
||
systemPlatformUser: getInputValue('setting-system-platform-user').trim(),
|
||
platformUserId: getInputValue('setting-platform-user-id').trim(),
|
||
platformId: getInputValue('setting-platform-id').trim(),
|
||
withClassify: document.getElementById('setting-with-classify')?.checked || false,
|
||
resetSessionMode: document.getElementById('setting-reset-session-mode')?.checked !== false
|
||
}
|
||
|
||
return updatedSettings
|
||
}
|
||
|
||
/**
|
||
* Сохранить настройки на сервер
|
||
*/
|
||
export async function save() {
|
||
const saveBtn = document.getElementById('save-settings-btn')
|
||
|
||
if (!saveBtn) {
|
||
console.error('Save settings button not found')
|
||
return
|
||
}
|
||
|
||
saveBtn.disabled = true
|
||
saveBtn.textContent = 'Сохранение...'
|
||
|
||
try {
|
||
const updatedSettings = read()
|
||
|
||
if (!updatedSettings) {
|
||
throw new Error('Failed to read settings from dialog')
|
||
}
|
||
|
||
await settingsService.saveToServer(updatedSettings)
|
||
showToast('Настройки сохранены на сервере', 'success')
|
||
close()
|
||
} catch (error) {
|
||
console.error('Failed to save settings:', error)
|
||
showToast(`Ошибка сохранения: ${error.message}`, 'error')
|
||
} finally {
|
||
saveBtn.disabled = false
|
||
saveBtn.textContent = 'Сохранить'
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Сбросить настройки к дефолтным
|
||
*/
|
||
export async function reset() {
|
||
if (!confirm('Сбросить все настройки к значениям по умолчанию?')) {
|
||
return
|
||
}
|
||
|
||
try {
|
||
const resetSettings = { ...defaultSettings }
|
||
await settingsService.saveToServer(resetSettings)
|
||
populate()
|
||
showToast('Настройки сброшены и сохранены на сервере', 'success')
|
||
} catch (error) {
|
||
console.error('Failed to reset settings:', error)
|
||
showToast(`Ошибка сброса: ${error.message}`, 'error')
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Экспортировать настройки в JSON файл
|
||
*/
|
||
export function exportSettings() {
|
||
const filename = 'brief-bench-settings.json'
|
||
downloadJSON(appState.settings, filename)
|
||
showToast('Настройки экспортированы в ' + filename, 'success')
|
||
}
|
||
|
||
/**
|
||
* Импортировать настройки из JSON файла
|
||
*/
|
||
export async function importSettings() {
|
||
const input = document.createElement('input')
|
||
input.type = 'file'
|
||
input.accept = 'application/json'
|
||
|
||
input.onchange = async (e) => {
|
||
const file = e.target.files[0]
|
||
if (!file) return
|
||
|
||
try {
|
||
const settings = await loadFileAsJSON(file)
|
||
|
||
// Validate basic structure
|
||
if (typeof settings !== 'object' || settings === null) {
|
||
throw new Error('Файл настроек должен содержать JSON объект')
|
||
}
|
||
|
||
// Merge with defaults to ensure all required fields exist
|
||
const mergedSettings = {
|
||
...defaultSettings,
|
||
...settings
|
||
}
|
||
|
||
// Save to server
|
||
await settingsService.saveToServer(mergedSettings)
|
||
populate()
|
||
showToast('Настройки импортированы и сохранены на сервере', 'success')
|
||
} catch (error) {
|
||
console.error('Failed to import settings:', error)
|
||
showToast(`Ошибка импорта: ${error.message}`, 'error')
|
||
}
|
||
}
|
||
|
||
input.click()
|
||
}
|
||
|
||
/**
|
||
* Обработчик изменения окружения в селекторе
|
||
*/
|
||
export function handleEnvironmentChange() {
|
||
populate()
|
||
}
|
||
|
||
/**
|
||
* Обработчик изменения API режима
|
||
*/
|
||
export function handleApiModeChange() {
|
||
const apiModeSelect = document.getElementById('setting-api-mode')
|
||
if (apiModeSelect) {
|
||
const apiMode = apiModeSelect.value
|
||
toggleBackendSettings(apiMode === 'backend')
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Инициализация обработчиков событий
|
||
*/
|
||
export function setupListeners() {
|
||
const openBtn = document.getElementById('settings-btn')
|
||
const closeBtn = document.getElementById('close-settings-btn')
|
||
const saveBtn = document.getElementById('save-settings-btn')
|
||
const resetBtn = document.getElementById('reset-settings-btn')
|
||
const exportBtn = document.getElementById('export-settings-btn')
|
||
const importBtn = document.getElementById('import-settings-btn')
|
||
const envSelector = document.getElementById('settings-env-selector')
|
||
const apiModeSelect = document.getElementById('setting-api-mode')
|
||
|
||
if (openBtn) {
|
||
openBtn.addEventListener('click', open)
|
||
}
|
||
|
||
if (closeBtn) {
|
||
closeBtn.addEventListener('click', close)
|
||
}
|
||
|
||
if (saveBtn) {
|
||
saveBtn.addEventListener('click', save)
|
||
}
|
||
|
||
if (resetBtn) {
|
||
resetBtn.addEventListener('click', reset)
|
||
}
|
||
|
||
if (exportBtn) {
|
||
exportBtn.addEventListener('click', exportSettings)
|
||
}
|
||
|
||
if (importBtn) {
|
||
importBtn.addEventListener('click', importSettings)
|
||
}
|
||
|
||
if (envSelector) {
|
||
envSelector.addEventListener('change', handleEnvironmentChange)
|
||
}
|
||
|
||
if (apiModeSelect) {
|
||
apiModeSelect.addEventListener('change', handleApiModeChange)
|
||
}
|
||
}
|
||
|
||
// Export as default object
|
||
export default {
|
||
open,
|
||
close,
|
||
populate,
|
||
read,
|
||
save,
|
||
reset,
|
||
exportSettings,
|
||
importSettings,
|
||
toggleBackendSettings,
|
||
handleEnvironmentChange,
|
||
handleApiModeChange,
|
||
setupListeners
|
||
}
|