brief-rags-bench/static/js/ui/settings.ui.js

313 lines
8.9 KiB
JavaScript
Raw Normal View History

2025-12-25 09:47:11 +01:00
/**
* 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('open-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
}