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('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
|
|||
|
|
}
|