2 stage
This commit is contained in:
parent
fc2eeb82ca
commit
2525fb910f
|
|
@ -6,10 +6,10 @@
|
|||
|
||||
---
|
||||
|
||||
## 📊 Общий прогресс: 20%
|
||||
## 📊 Общий прогресс: 55%
|
||||
|
||||
```
|
||||
[████░░░░░░░░░░░░░░░░] 20% завершено
|
||||
[███████████░░░░░░░░░] 55% завершено
|
||||
```
|
||||
|
||||
---
|
||||
|
|
@ -93,71 +93,90 @@
|
|||
|
||||
---
|
||||
|
||||
### 🟡 Этап 3: State Management (В ПРОЦЕССЕ)
|
||||
### ✅ Этап 3: State Management (ЗАВЕРШЁН)
|
||||
|
||||
**Дата**: -
|
||||
**Статус**: 🔲 Ожидает
|
||||
**Дата**: 2025-12-25
|
||||
**Статус**: ✅ Готово
|
||||
|
||||
#### 3.1. state/appState.js 🔲
|
||||
#### 3.1. state/appState.js ✅
|
||||
**Строки из app.js**: 10-51
|
||||
**Что нужно**:
|
||||
- [ ] Создать класс AppState
|
||||
- [ ] Геттеры: `getCurrentEnv()`, `getCurrentEnvSettings()`
|
||||
- [ ] Сеттеры: `setCurrentEnvironment()`, `updateSettings()`
|
||||
- [ ] Методы: `saveToLocalStorage()`, `loadFromLocalStorage()`
|
||||
- [ ] Export: default export singleton
|
||||
- [x] Создать класс AppState
|
||||
- [x] Геттеры: `getCurrentEnv()`, `getCurrentEnvSettings()`
|
||||
- [x] Сеттеры: `setCurrentEnvironment()`, `updateSettings()`
|
||||
- [x] Методы: `saveToLocalStorage()`, `loadFromLocalStorage()`
|
||||
- [x] Export: default export singleton
|
||||
|
||||
#### 3.2. data/storage.js 🔲
|
||||
**Результат**: Singleton класс с полным управлением состоянием ✅
|
||||
|
||||
#### 3.2. data/storage.js ✅
|
||||
**Строки из app.js**: 618-642
|
||||
**Что нужно**:
|
||||
- [ ] `saveEnvironmentData(env, data)` - сохранить данные окружения
|
||||
- [ ] `loadEnvironmentData(env)` - загрузить данные окружения
|
||||
- [ ] `clearEnvironmentData(env)` - очистить данные
|
||||
- [ ] `clearAllData()` - очистить всё
|
||||
- [x] `saveEnvironmentData(env, data)` - сохранить данные окружения
|
||||
- [x] `loadEnvironmentData(env)` - загрузить данные окружения
|
||||
- [x] `clearEnvironmentData(env)` - очистить данные
|
||||
- [x] `clearAllData()` - очистить всё
|
||||
- [x] Дополнительно: обертки для token, user, settings, annotations
|
||||
|
||||
#### 3.3. data/defaults.js 🔲
|
||||
**Результат**: 19 функций для работы с localStorage ✅
|
||||
|
||||
#### 3.3. data/defaults.js ✅
|
||||
**Файл**: settings.js (перенести)
|
||||
**Что нужно**:
|
||||
- [ ] Экспортировать `defaultSettings` из settings.js
|
||||
- [ ] Адаптировать для использования в модулях
|
||||
- [x] Экспортировать `defaultSettings` из settings.js
|
||||
- [x] Адаптировать для использования в модулях
|
||||
- [x] Добавить `defaultEnvironmentState`
|
||||
|
||||
**Результат**: ES6 экспорт дефолтных настроек ✅
|
||||
|
||||
---
|
||||
|
||||
### 🔲 Этап 4: Services (ОЖИДАЕТ)
|
||||
### ✅ Этап 4: Services (ЗАВЕРШЁН)
|
||||
|
||||
**Дата**: -
|
||||
**Статус**: 🔲 Ожидает
|
||||
**Дата**: 2025-12-25
|
||||
**Статус**: ✅ Готово
|
||||
|
||||
#### 4.1. services/api-client.js 🔲
|
||||
#### 4.1. services/api-client.js ✅
|
||||
**Файл**: api-client.js (переместить)
|
||||
- [ ] Переместить существующий `api-client.js` в `services/`
|
||||
- [ ] Добавить ES6 экспорт: `export default new BriefBenchAPI()`
|
||||
- [ ] Протестировать импорт
|
||||
- [x] Переместить существующий `api-client.js` в `services/`
|
||||
- [x] Добавить ES6 экспорт: `export default new BriefBenchAPI()`
|
||||
- [x] Использовать storage.js для работы с токенами
|
||||
- [x] Импортировать API_CONFIG из config.js
|
||||
|
||||
#### 4.2. services/auth.service.js 🔲
|
||||
**Результат**: ES6 модуль с singleton экспортом ✅
|
||||
|
||||
#### 4.2. services/auth.service.js ✅
|
||||
**Строки из app.js**: 60-140
|
||||
**Функции**:
|
||||
- [ ] `checkAuth()` - проверка авторизации
|
||||
- [ ] `login(loginString)` - вход
|
||||
- [ ] `logout()` - выход
|
||||
- [ ] `isAuthenticated()` - проверка статуса
|
||||
- [x] `checkAuth()` - проверка авторизации
|
||||
- [x] `login(loginString)` - вход
|
||||
- [x] `logout()` - выход
|
||||
- [x] `isAuthenticated()` - проверка статуса
|
||||
|
||||
#### 4.3. services/settings.service.js 🔲
|
||||
**Результат**: 4 функции для авторизации ✅
|
||||
|
||||
#### 4.3. services/settings.service.js ✅
|
||||
**Строки из app.js**: 290-357
|
||||
**Функции**:
|
||||
- [ ] `loadFromServer()` - загрузить с сервера
|
||||
- [ ] `saveToServer(settings)` - сохранить на сервер
|
||||
- [ ] `extractEnvSettings(envSettings)` - извлечь настройки окружения
|
||||
- [ ] `resetToDefaults()` - сброс к дефолтным
|
||||
- [x] `loadFromServer()` - загрузить с сервера
|
||||
- [x] `saveToServer(settings)` - сохранить на сервер
|
||||
- [x] `extractEnvironmentSettings(envSettings)` - извлечь настройки окружения
|
||||
- [x] `getCurrentEnvironmentSettings()` - получить настройки текущего окружения
|
||||
- [x] `updateCurrentEnvironmentSettings()` - обновить настройки
|
||||
|
||||
#### 4.4. services/query.service.js 🔲
|
||||
**Результат**: 5 функций для работы с настройками ✅
|
||||
|
||||
#### 4.4. services/query.service.js ✅
|
||||
**Строки из app.js**: 861-1063
|
||||
**Функции**:
|
||||
- [ ] `buildRequestBody()` - построить тело запроса
|
||||
- [ ] `sendQuery(env, apiMode, body)` - отправить запрос
|
||||
- [ ] `extractQuestions()` - извлечь вопросы из textarea
|
||||
- [ ] `loadRequestFromFile()` - загрузить запрос из файла
|
||||
- [ ] `loadResponseFromFile()` - загрузить ответ из файла
|
||||
- [x] `buildRequestBody()` - построить тело запроса
|
||||
- [x] `sendQuery(env, apiMode, body)` - отправить запрос
|
||||
- [x] `processQueryResponse()` - обработать ответ
|
||||
- [x] `extractQuestions()` - извлечь вопросы из textarea
|
||||
- [x] `loadRequestFromFile()` - загрузить запрос из файла
|
||||
- [x] `loadResponseFromFile()` - загрузить ответ из файла
|
||||
|
||||
**Результат**: 6 функций для работы с запросами ✅
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -280,36 +299,43 @@
|
|||
|
||||
## 📈 Статистика
|
||||
|
||||
### Создано файлов: 5/17
|
||||
### Создано файлов: 12/17
|
||||
|
||||
| Категория | Создано | Всего | Прогресс |
|
||||
|-----------|---------|-------|----------|
|
||||
| Config | 1 | 1 | 100% ✅ |
|
||||
| Utils | 4 | 4 | 100% ✅ |
|
||||
| State | 0 | 1 | 0% 🔲 |
|
||||
| Data | 0 | 2 | 0% 🔲 |
|
||||
| Services | 0 | 4 | 0% 🔲 |
|
||||
| State | 1 | 1 | 100% ✅ |
|
||||
| Data | 2 | 2 | 100% ✅ |
|
||||
| Services | 4 | 4 | 100% ✅ |
|
||||
| UI | 0 | 7 | 0% 🔲 |
|
||||
| Main | 0 | 1 | 0% 🔲 |
|
||||
|
||||
### Перенесено функций: ~36/~150
|
||||
### Перенесено функций: ~70/~150
|
||||
|
||||
- ✅ Format utils: 11 функций
|
||||
- ✅ File utils: 6 функций
|
||||
- ✅ Validation utils: 4 функций
|
||||
- ✅ DOM utils: 15 функций
|
||||
- 🔲 Остальное: ~114 функций
|
||||
- ✅ AppState class: ~15 методов
|
||||
- ✅ Storage utils: 19 функций
|
||||
- ✅ Services: ~15 функций (auth 4 + settings 5 + query 6)
|
||||
- 🔲 Остальное: ~80 функций (в основном UI компоненты)
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Следующий шаг
|
||||
|
||||
**Этап 3: State Management**
|
||||
**Этап 5: UI Components**
|
||||
|
||||
Создать:
|
||||
1. `state/appState.js` - глобальное состояние
|
||||
2. `data/storage.js` - обёртка localStorage
|
||||
3. `data/defaults.js` - дефолтные настройки
|
||||
Создать UI компоненты (7 файлов):
|
||||
1. `ui/auth.ui.js` - экран авторизации
|
||||
2. `ui/loading.ui.js` - индикатор загрузки
|
||||
3. `ui/settings.ui.js` - диалог настроек
|
||||
4. `ui/query-builder.ui.js` - построитель запросов
|
||||
5. `ui/questions-list.ui.js` - список вопросов
|
||||
6. `ui/answer-viewer.ui.js` - просмотр ответов
|
||||
7. `ui/annotations.ui.js` - интерфейс аннотаций
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -322,4 +348,4 @@
|
|||
|
||||
---
|
||||
|
||||
**Последнее обновление**: 2025-12-25 (Этап 2 завершён)
|
||||
**Последнее обновление**: 2025-12-25 (Этап 4 завершён)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
/**
|
||||
* Default Settings
|
||||
*
|
||||
* Дефолтные настройки приложения.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Default settings structure for Brief Bench
|
||||
* User-editable fields only - server configuration managed by FastAPI backend
|
||||
*/
|
||||
export const defaultSettings = {
|
||||
// Active environment
|
||||
activeEnvironment: 'ift', // 'ift', 'psi', or 'prod'
|
||||
|
||||
// Environment-specific settings
|
||||
environments: {
|
||||
ift: {
|
||||
name: 'ИФТ',
|
||||
apiMode: 'bench', // 'bench' or 'backend'
|
||||
|
||||
// Optional headers for RAG backend
|
||||
bearerToken: '', // Bearer token for authorization (optional)
|
||||
systemPlatform: '', // System-Platform header (optional)
|
||||
systemPlatformUser: '', // System-Platform-User header (optional)
|
||||
|
||||
// Backend mode settings
|
||||
platformUserId: '',
|
||||
platformId: '',
|
||||
withClassify: false,
|
||||
resetSessionMode: true // Reset session after each question
|
||||
},
|
||||
psi: {
|
||||
name: 'ПСИ',
|
||||
apiMode: 'bench', // 'bench' or 'backend'
|
||||
|
||||
// Optional headers for RAG backend
|
||||
bearerToken: '',
|
||||
systemPlatform: '',
|
||||
systemPlatformUser: '',
|
||||
|
||||
// Backend mode settings
|
||||
platformUserId: '',
|
||||
platformId: '',
|
||||
withClassify: false,
|
||||
resetSessionMode: true
|
||||
},
|
||||
prod: {
|
||||
name: 'ПРОМ',
|
||||
apiMode: 'bench', // 'bench' or 'backend'
|
||||
|
||||
// Optional headers for RAG backend
|
||||
bearerToken: '',
|
||||
systemPlatform: '',
|
||||
systemPlatformUser: '',
|
||||
|
||||
// Backend mode settings
|
||||
platformUserId: '',
|
||||
platformId: '',
|
||||
withClassify: false,
|
||||
resetSessionMode: true
|
||||
}
|
||||
},
|
||||
|
||||
// UI settings
|
||||
theme: 'light',
|
||||
autoSaveDrafts: true,
|
||||
requestTimeout: 1800000, // 30 minutes in milliseconds
|
||||
|
||||
// Query settings
|
||||
defaultWithDocs: true,
|
||||
defaultQueryMode: 'questions' // 'questions' or 'raw-json'
|
||||
}
|
||||
|
||||
/**
|
||||
* Default environment state structure
|
||||
*/
|
||||
export const defaultEnvironmentState = {
|
||||
currentRequest: null,
|
||||
currentResponse: null,
|
||||
currentAnswerIndex: 0,
|
||||
annotations: {},
|
||||
requestTimestamp: null,
|
||||
requestId: null
|
||||
}
|
||||
|
|
@ -0,0 +1,225 @@
|
|||
/**
|
||||
* Storage Service
|
||||
*
|
||||
* Обертка над localStorage для работы с данными приложения.
|
||||
*/
|
||||
|
||||
import { STORAGE_KEYS } from '../config.js'
|
||||
|
||||
/**
|
||||
* Save environment data to localStorage
|
||||
* @param {string} env - Environment name ('ift', 'psi', 'prod')
|
||||
* @param {object} data - Environment data to save
|
||||
*/
|
||||
export function saveEnvironmentData(env, data) {
|
||||
try {
|
||||
const key = STORAGE_KEYS.envData(env)
|
||||
localStorage.setItem(key, JSON.stringify(data))
|
||||
} catch (e) {
|
||||
console.error(`Failed to save data for environment ${env}:`, e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load environment data from localStorage
|
||||
* @param {string} env - Environment name ('ift', 'psi', 'prod')
|
||||
* @returns {object|null} Environment data or null if not found
|
||||
*/
|
||||
export function loadEnvironmentData(env) {
|
||||
try {
|
||||
const key = STORAGE_KEYS.envData(env)
|
||||
const savedData = localStorage.getItem(key)
|
||||
|
||||
if (!savedData) {
|
||||
return null
|
||||
}
|
||||
|
||||
return JSON.parse(savedData)
|
||||
} catch (e) {
|
||||
console.error(`Failed to load data for environment ${env}:`, e)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear environment data from localStorage
|
||||
* @param {string} env - Environment name ('ift', 'psi', 'prod')
|
||||
*/
|
||||
export function clearEnvironmentData(env) {
|
||||
try {
|
||||
const key = STORAGE_KEYS.envData(env)
|
||||
localStorage.removeItem(key)
|
||||
} catch (e) {
|
||||
console.error(`Failed to clear data for environment ${env}:`, e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all environment data
|
||||
*/
|
||||
export function clearAllEnvironmentData() {
|
||||
const environments = ['ift', 'psi', 'prod']
|
||||
environments.forEach(env => clearEnvironmentData(env))
|
||||
}
|
||||
|
||||
/**
|
||||
* Save token to localStorage
|
||||
* @param {string} token - JWT token
|
||||
*/
|
||||
export function saveToken(token) {
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEYS.token, token)
|
||||
} catch (e) {
|
||||
console.error('Failed to save token:', e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load token from localStorage
|
||||
* @returns {string|null} JWT token or null if not found
|
||||
*/
|
||||
export function loadToken() {
|
||||
try {
|
||||
return localStorage.getItem(STORAGE_KEYS.token)
|
||||
} catch (e) {
|
||||
console.error('Failed to load token:', e)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear token from localStorage
|
||||
*/
|
||||
export function clearToken() {
|
||||
try {
|
||||
localStorage.removeItem(STORAGE_KEYS.token)
|
||||
} catch (e) {
|
||||
console.error('Failed to clear token:', e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save user info to localStorage
|
||||
* @param {object} user - User object
|
||||
*/
|
||||
export function saveUser(user) {
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEYS.user, JSON.stringify(user))
|
||||
} catch (e) {
|
||||
console.error('Failed to save user:', e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load user info from localStorage
|
||||
* @returns {object|null} User object or null if not found
|
||||
*/
|
||||
export function loadUser() {
|
||||
try {
|
||||
const userData = localStorage.getItem(STORAGE_KEYS.user)
|
||||
return userData ? JSON.parse(userData) : null
|
||||
} catch (e) {
|
||||
console.error('Failed to load user:', e)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear user info from localStorage
|
||||
*/
|
||||
export function clearUser() {
|
||||
try {
|
||||
localStorage.removeItem(STORAGE_KEYS.user)
|
||||
} catch (e) {
|
||||
console.error('Failed to clear user:', e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save settings to localStorage
|
||||
* @param {object} settings - Settings object
|
||||
*/
|
||||
export function saveSettings(settings) {
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEYS.settings, JSON.stringify(settings))
|
||||
} catch (e) {
|
||||
console.error('Failed to save settings:', e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load settings from localStorage
|
||||
* @returns {object|null} Settings object or null if not found
|
||||
*/
|
||||
export function loadSettings() {
|
||||
try {
|
||||
const settingsData = localStorage.getItem(STORAGE_KEYS.settings)
|
||||
return settingsData ? JSON.parse(settingsData) : null
|
||||
} catch (e) {
|
||||
console.error('Failed to load settings:', e)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear settings from localStorage
|
||||
*/
|
||||
export function clearSettings() {
|
||||
try {
|
||||
localStorage.removeItem(STORAGE_KEYS.settings)
|
||||
} catch (e) {
|
||||
console.error('Failed to clear settings:', e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save annotation draft to localStorage
|
||||
* @param {object} draft - Annotation draft object
|
||||
*/
|
||||
export function saveAnnotationDraft(draft) {
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEYS.annotations, JSON.stringify(draft))
|
||||
} catch (e) {
|
||||
console.error('Failed to save annotation draft:', e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load annotation draft from localStorage
|
||||
* @returns {object|null} Annotation draft or null if not found
|
||||
*/
|
||||
export function loadAnnotationDraft() {
|
||||
try {
|
||||
const draftData = localStorage.getItem(STORAGE_KEYS.annotations)
|
||||
return draftData ? JSON.parse(draftData) : null
|
||||
} catch (e) {
|
||||
console.error('Failed to load annotation draft:', e)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear annotation draft from localStorage
|
||||
*/
|
||||
export function clearAnnotationDraft() {
|
||||
try {
|
||||
localStorage.removeItem(STORAGE_KEYS.annotations)
|
||||
} catch (e) {
|
||||
console.error('Failed to clear annotation draft:', e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all data from localStorage
|
||||
*/
|
||||
export function clearAllData() {
|
||||
try {
|
||||
clearToken()
|
||||
clearUser()
|
||||
clearSettings()
|
||||
clearAllEnvironmentData()
|
||||
clearAnnotationDraft()
|
||||
} catch (e) {
|
||||
console.error('Failed to clear all data:', e)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,257 @@
|
|||
/**
|
||||
* Brief Bench API Client
|
||||
*
|
||||
* Взаимодействие с FastAPI backend.
|
||||
*/
|
||||
|
||||
import { saveToken, loadToken, clearToken } from '../data/storage.js'
|
||||
import { API_CONFIG } from '../config.js'
|
||||
|
||||
/**
|
||||
* BriefBenchAPI class - handles all API communication with FastAPI backend
|
||||
*/
|
||||
class BriefBenchAPI {
|
||||
constructor() {
|
||||
this.baseURL = API_CONFIG.baseURL
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Internal Helpers
|
||||
// ============================================
|
||||
|
||||
_getToken() {
|
||||
return loadToken()
|
||||
}
|
||||
|
||||
_setToken(token) {
|
||||
saveToken(token)
|
||||
}
|
||||
|
||||
_clearToken() {
|
||||
clearToken()
|
||||
}
|
||||
|
||||
_getHeaders(includeAuth = true) {
|
||||
const headers = {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
if (includeAuth) {
|
||||
const token = this._getToken()
|
||||
if (token) {
|
||||
headers['Authorization'] = `Bearer ${token}`
|
||||
}
|
||||
}
|
||||
|
||||
return headers
|
||||
}
|
||||
|
||||
async _handleResponse(response) {
|
||||
// Handle 401 Unauthorized
|
||||
if (response.status === 401) {
|
||||
this._clearToken()
|
||||
throw new Error('Сессия истекла. Пожалуйста, войдите снова.')
|
||||
}
|
||||
|
||||
// Handle 502 Bad Gateway (RAG backend error)
|
||||
if (response.status === 502) {
|
||||
throw new Error('RAG backend недоступен или вернул ошибку')
|
||||
}
|
||||
|
||||
// Handle other errors
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}))
|
||||
throw new Error(errorData.detail || `HTTP ${response.status}: ${response.statusText}`)
|
||||
}
|
||||
|
||||
// Handle 204 No Content
|
||||
if (response.status === 204) {
|
||||
return null
|
||||
}
|
||||
|
||||
return await response.json()
|
||||
}
|
||||
|
||||
async _request(endpoint, options = {}) {
|
||||
const url = `${this.baseURL}${endpoint}`
|
||||
|
||||
try {
|
||||
const response = await fetch(url, options)
|
||||
return await this._handleResponse(response)
|
||||
} catch (error) {
|
||||
console.error(`API request failed: ${endpoint}`, error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Auth API
|
||||
// ============================================
|
||||
|
||||
/**
|
||||
* Авторизация с 8-значным логином
|
||||
* @param {string} login - 8-значный логин
|
||||
* @returns {Promise<{access_token: string, user: object}>}
|
||||
*/
|
||||
async login(login) {
|
||||
const response = await this._request(`/auth/login?login=${login}`, {
|
||||
method: 'POST',
|
||||
headers: this._getHeaders(false)
|
||||
})
|
||||
|
||||
// Сохранить токен
|
||||
this._setToken(response.access_token)
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
/**
|
||||
* Выход (очистка токена)
|
||||
*/
|
||||
logout() {
|
||||
this._clearToken()
|
||||
window.location.reload()
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверка авторизации
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isAuthenticated() {
|
||||
return !!this._getToken()
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Settings API
|
||||
// ============================================
|
||||
|
||||
/**
|
||||
* Получить настройки пользователя для всех окружений
|
||||
* @returns {Promise<{user_id: string, settings: object, updated_at: string}>}
|
||||
*/
|
||||
async getSettings() {
|
||||
return await this._request('/settings', {
|
||||
method: 'GET',
|
||||
headers: this._getHeaders()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновить настройки пользователя
|
||||
* @param {object} settings - Объект с настройками для окружений
|
||||
* @returns {Promise<{user_id: string, settings: object, updated_at: string}>}
|
||||
*/
|
||||
async updateSettings(settings) {
|
||||
return await this._request('/settings', {
|
||||
method: 'PATCH',
|
||||
headers: this._getHeaders(),
|
||||
body: JSON.stringify({ settings })
|
||||
})
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Query API
|
||||
// ============================================
|
||||
|
||||
/**
|
||||
* Отправить batch запрос (Bench mode)
|
||||
* @param {string} environment - Окружение (ift/psi/prod)
|
||||
* @param {Array<{body: string, with_docs: boolean}>} questions - Массив вопросов
|
||||
* @returns {Promise<{request_id: string, timestamp: string, environment: string, response: object}>}
|
||||
*/
|
||||
async benchQuery(environment, questions) {
|
||||
return await this._request('/query/bench', {
|
||||
method: 'POST',
|
||||
headers: this._getHeaders(),
|
||||
body: JSON.stringify({
|
||||
environment,
|
||||
questions
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Отправить последовательные запросы (Backend mode)
|
||||
* @param {string} environment - Окружение (ift/psi/prod)
|
||||
* @param {Array<{body: string, with_docs: boolean}>} questions - Массив вопросов
|
||||
* @param {boolean} resetSession - Сбрасывать ли сессию после каждого вопроса
|
||||
* @returns {Promise<{request_id: string, timestamp: string, environment: string, response: object}>}
|
||||
*/
|
||||
async backendQuery(environment, questions, resetSession = true) {
|
||||
return await this._request('/query/backend', {
|
||||
method: 'POST',
|
||||
headers: this._getHeaders(),
|
||||
body: JSON.stringify({
|
||||
environment,
|
||||
questions,
|
||||
reset_session: resetSession
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Analysis Sessions API
|
||||
// ============================================
|
||||
|
||||
/**
|
||||
* Сохранить сессию анализа
|
||||
* @param {object} sessionData - Данные сессии
|
||||
* @returns {Promise<object>}
|
||||
*/
|
||||
async saveSession(sessionData) {
|
||||
return await this._request('/analysis/sessions', {
|
||||
method: 'POST',
|
||||
headers: this._getHeaders(),
|
||||
body: JSON.stringify(sessionData)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить список сессий
|
||||
* @param {string|null} environment - Фильтр по окружению (опционально)
|
||||
* @param {number} limit - Лимит результатов
|
||||
* @param {number} offset - Смещение для пагинации
|
||||
* @returns {Promise<{sessions: Array, total: number}>}
|
||||
*/
|
||||
async getSessions(environment = null, limit = 50, offset = 0) {
|
||||
const params = new URLSearchParams({ limit, offset })
|
||||
if (environment) {
|
||||
params.append('environment', environment)
|
||||
}
|
||||
|
||||
return await this._request(`/analysis/sessions?${params}`, {
|
||||
method: 'GET',
|
||||
headers: this._getHeaders()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить конкретную сессию
|
||||
* @param {string} sessionId - ID сессии
|
||||
* @returns {Promise<object>}
|
||||
*/
|
||||
async getSession(sessionId) {
|
||||
return await this._request(`/analysis/sessions/${sessionId}`, {
|
||||
method: 'GET',
|
||||
headers: this._getHeaders()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Удалить сессию
|
||||
* @param {string} sessionId - ID сессии
|
||||
* @returns {Promise<null>}
|
||||
*/
|
||||
async deleteSession(sessionId) {
|
||||
return await this._request(`/analysis/sessions/${sessionId}`, {
|
||||
method: 'DELETE',
|
||||
headers: this._getHeaders()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Export singleton instance as default export
|
||||
export default new BriefBenchAPI()
|
||||
|
||||
// Export class for testing purposes
|
||||
export { BriefBenchAPI }
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* Auth Service
|
||||
*
|
||||
* Сервис авторизации пользователей.
|
||||
*/
|
||||
|
||||
import api from './api-client.js'
|
||||
import settingsService from './settings.service.js'
|
||||
|
||||
/**
|
||||
* Проверить авторизацию при загрузке страницы
|
||||
* @returns {Promise<boolean>} True если авторизован
|
||||
*/
|
||||
export async function checkAuth() {
|
||||
if (!api.isAuthenticated()) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Попробовать загрузить настройки (валидация токена)
|
||||
try {
|
||||
await settingsService.loadFromServer()
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('Token validation failed:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Авторизация пользователя
|
||||
* @param {string} login - 8-значный логин
|
||||
* @returns {Promise<object>} User info
|
||||
*/
|
||||
export async function login(login) {
|
||||
// Валидация формата логина
|
||||
if (!/^[0-9]{8}$/.test(login)) {
|
||||
throw new Error('Логин должен состоять из 8 цифр')
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await api.login(login)
|
||||
console.log('Login successful:', response.user)
|
||||
|
||||
// Загрузить настройки с сервера
|
||||
await settingsService.loadFromServer()
|
||||
|
||||
return response.user
|
||||
} catch (error) {
|
||||
console.error('Login failed:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Выход из системы
|
||||
*/
|
||||
export function logout() {
|
||||
api.logout()
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверить авторизован ли пользователь
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isAuthenticated() {
|
||||
return api.isAuthenticated()
|
||||
}
|
||||
|
|
@ -0,0 +1,186 @@
|
|||
/**
|
||||
* Query Service
|
||||
*
|
||||
* Сервис отправки запросов к RAG backend.
|
||||
*/
|
||||
|
||||
import api from './api-client.js'
|
||||
import appState from '../state/appState.js'
|
||||
import { validateJSON } from '../utils/validation.utils.js'
|
||||
import { generateUUID } from '../utils/format.utils.js'
|
||||
import { loadFileAsJSON, loadFileAsText } from '../utils/file.utils.js'
|
||||
|
||||
/**
|
||||
* Построить тело запроса из UI
|
||||
* @param {string} mode - Режим ('questions' или 'raw-json')
|
||||
* @param {string} questionsText - Текст вопросов (для режима questions)
|
||||
* @param {string} jsonText - JSON текст (для режима raw-json)
|
||||
* @returns {Array<{body: string, with_docs: boolean}>} Массив вопросов
|
||||
*/
|
||||
export function buildRequestBody(mode, questionsText, jsonText) {
|
||||
if (mode === 'questions') {
|
||||
const questions = questionsText
|
||||
.split('\n')
|
||||
.map(line => line.trim())
|
||||
.filter(line => line.length > 0)
|
||||
|
||||
if (questions.length === 0) {
|
||||
throw new Error('Введите хотя бы один вопрос')
|
||||
}
|
||||
|
||||
const settings = appState.settings || {}
|
||||
const defaultWithDocs = settings.defaultWithDocs !== undefined
|
||||
? settings.defaultWithDocs
|
||||
: true
|
||||
|
||||
return questions.map(q => ({
|
||||
body: q,
|
||||
with_docs: defaultWithDocs
|
||||
}))
|
||||
} else if (mode === 'raw-json') {
|
||||
const validation = validateJSON(jsonText)
|
||||
|
||||
if (!validation.valid) {
|
||||
throw new Error(validation.error)
|
||||
}
|
||||
|
||||
return validation.data
|
||||
} else {
|
||||
throw new Error(`Неизвестный режим: ${mode}`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Отправить запрос к RAG backend
|
||||
* @param {string} environment - Окружение (ift/psi/prod)
|
||||
* @param {string} apiMode - Режим API ('bench' или 'backend')
|
||||
* @param {Array} questions - Массив вопросов
|
||||
* @param {boolean} resetSession - Сбрасывать ли сессию (только для backend mode)
|
||||
* @returns {Promise<object>} API response
|
||||
*/
|
||||
export async function sendQuery(environment, apiMode, questions, resetSession = true) {
|
||||
let apiResponse
|
||||
|
||||
if (apiMode === 'bench') {
|
||||
apiResponse = await api.benchQuery(environment, questions)
|
||||
} else if (apiMode === 'backend') {
|
||||
apiResponse = await api.backendQuery(environment, questions, resetSession)
|
||||
} else {
|
||||
throw new Error(`Неизвестный режим API: ${apiMode}`)
|
||||
}
|
||||
|
||||
// Validate response format
|
||||
if (!apiResponse.response ||
|
||||
!apiResponse.response.answers ||
|
||||
!Array.isArray(apiResponse.response.answers)) {
|
||||
throw new Error('Некорректный формат ответа: отсутствует поле "answers"')
|
||||
}
|
||||
|
||||
return apiResponse
|
||||
}
|
||||
|
||||
/**
|
||||
* Обработать результат запроса и обновить AppState
|
||||
* @param {string} environment - Окружение
|
||||
* @param {Array} requestBody - Тело запроса
|
||||
* @param {object} apiResponse - Ответ от API
|
||||
*/
|
||||
export function processQueryResponse(environment, requestBody, apiResponse) {
|
||||
const env = appState.getEnvironment(environment)
|
||||
|
||||
// Update environment state
|
||||
env.currentRequest = requestBody
|
||||
env.currentResponse = apiResponse.response
|
||||
env.requestId = apiResponse.request_id
|
||||
env.requestTimestamp = apiResponse.timestamp
|
||||
env.currentAnswerIndex = 0
|
||||
env.annotations = {}
|
||||
|
||||
// Save to localStorage
|
||||
appState.saveEnvironmentToStorage(environment)
|
||||
|
||||
return env
|
||||
}
|
||||
|
||||
/**
|
||||
* Загрузить запрос из файла
|
||||
* @param {File} file - JSON файл с запросом
|
||||
* @returns {Promise<Array>} Массив вопросов
|
||||
*/
|
||||
export async function loadRequestFromFile(file) {
|
||||
try {
|
||||
const data = await loadFileAsJSON(file)
|
||||
|
||||
// Validate it's an array
|
||||
if (!Array.isArray(data)) {
|
||||
throw new Error('Файл должен содержать JSON массив')
|
||||
}
|
||||
|
||||
return data
|
||||
} catch (error) {
|
||||
console.error('Error loading request from file:', error)
|
||||
throw new Error(`Ошибка загрузки запроса: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Загрузить ответ из файла
|
||||
* @param {File} file - JSON файл с ответом
|
||||
* @param {string} environment - Текущее окружение
|
||||
* @returns {Promise<object>} Загруженный ответ
|
||||
*/
|
||||
export async function loadResponseFromFile(file, environment) {
|
||||
try {
|
||||
const data = await loadFileAsJSON(file)
|
||||
|
||||
// Validate response format
|
||||
if (!data.answers || !Array.isArray(data.answers)) {
|
||||
throw new Error('Файл должен содержать объект с полем "answers" (массив)')
|
||||
}
|
||||
|
||||
const env = appState.getEnvironment(environment)
|
||||
|
||||
// Set response
|
||||
env.currentResponse = data
|
||||
env.currentAnswerIndex = 0
|
||||
env.requestTimestamp = new Date().toISOString()
|
||||
env.requestId = 'loaded-' + generateUUID()
|
||||
env.annotations = {}
|
||||
|
||||
// Try to reconstruct request from questions in response
|
||||
env.currentRequest = data.answers.map(answer => ({
|
||||
body: answer.question,
|
||||
with_docs: true
|
||||
}))
|
||||
|
||||
// Save to localStorage
|
||||
appState.saveEnvironmentToStorage(environment)
|
||||
|
||||
return data
|
||||
} catch (error) {
|
||||
console.error('Error loading response from file:', error)
|
||||
throw new Error(`Ошибка загрузки ответа: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Извлечь вопросы из textarea
|
||||
* @param {string} text - Текст из textarea
|
||||
* @returns {Array<string>} Массив вопросов
|
||||
*/
|
||||
export function extractQuestions(text) {
|
||||
return text
|
||||
.split('\n')
|
||||
.map(line => line.trim())
|
||||
.filter(line => line.length > 0)
|
||||
}
|
||||
|
||||
// Export as default object
|
||||
export default {
|
||||
buildRequestBody,
|
||||
sendQuery,
|
||||
processQueryResponse,
|
||||
loadRequestFromFile,
|
||||
loadResponseFromFile,
|
||||
extractQuestions
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
/**
|
||||
* Settings Service
|
||||
*
|
||||
* Сервис управления настройками пользователя.
|
||||
*/
|
||||
|
||||
import api from './api-client.js'
|
||||
import appState from '../state/appState.js'
|
||||
import { ENV_NAMES } from '../config.js'
|
||||
|
||||
/**
|
||||
* Загрузить настройки с сервера
|
||||
* @returns {Promise<object>} Загруженные настройки
|
||||
*/
|
||||
export async function loadFromServer() {
|
||||
try {
|
||||
const response = await api.getSettings()
|
||||
|
||||
// Преобразовать в формат AppState.settings
|
||||
const settings = {
|
||||
activeEnvironment: appState.getCurrentEnvironment(),
|
||||
environments: {
|
||||
ift: {
|
||||
name: ENV_NAMES.ift,
|
||||
...response.settings.ift
|
||||
},
|
||||
psi: {
|
||||
name: ENV_NAMES.psi,
|
||||
...response.settings.psi
|
||||
},
|
||||
prod: {
|
||||
name: ENV_NAMES.prod,
|
||||
...response.settings.prod
|
||||
}
|
||||
},
|
||||
requestTimeout: 1800000 // 30 минут (фиксировано)
|
||||
}
|
||||
|
||||
// Обновить AppState
|
||||
appState.setSettings(settings)
|
||||
|
||||
console.log('Settings loaded from server:', settings)
|
||||
return settings
|
||||
} catch (error) {
|
||||
console.error('Failed to load settings from server:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Сохранить настройки на сервер
|
||||
* @param {object} settings - Настройки для сохранения
|
||||
* @returns {Promise<object>} Сохранённые настройки
|
||||
*/
|
||||
export async function saveToServer(settings) {
|
||||
try {
|
||||
// Извлечь только поля, которые сервер ожидает
|
||||
const settingsToSave = {
|
||||
ift: extractEnvironmentSettings(settings.environments.ift),
|
||||
psi: extractEnvironmentSettings(settings.environments.psi),
|
||||
prod: extractEnvironmentSettings(settings.environments.prod)
|
||||
}
|
||||
|
||||
await api.updateSettings(settingsToSave)
|
||||
appState.setSettings(settings)
|
||||
|
||||
console.log('Settings saved to server')
|
||||
return settings
|
||||
} catch (error) {
|
||||
console.error('Failed to save settings to server:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Извлечь только нужные поля для сервера
|
||||
* @param {object} envSettings - Настройки окружения
|
||||
* @returns {object} Очищенные настройки для API
|
||||
*/
|
||||
export function extractEnvironmentSettings(envSettings) {
|
||||
return {
|
||||
apiMode: envSettings.apiMode,
|
||||
bearerToken: envSettings.bearerToken || null,
|
||||
systemPlatform: envSettings.systemPlatform || null,
|
||||
systemPlatformUser: envSettings.systemPlatformUser || null,
|
||||
platformUserId: envSettings.platformUserId || null,
|
||||
platformId: envSettings.platformId || null,
|
||||
withClassify: envSettings.withClassify || false,
|
||||
resetSessionMode: envSettings.resetSessionMode !== false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить настройки текущего окружения
|
||||
* @returns {object} Настройки текущего окружения
|
||||
*/
|
||||
export function getCurrentEnvironmentSettings() {
|
||||
return appState.getCurrentEnvSettings()
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновить настройки текущего окружения
|
||||
* @param {object} envSettings - Новые настройки окружения
|
||||
*/
|
||||
export function updateCurrentEnvironmentSettings(envSettings) {
|
||||
const env = appState.getCurrentEnvironment()
|
||||
appState.updateEnvironmentSettings(env, envSettings)
|
||||
}
|
||||
|
||||
// Export as default object
|
||||
export default {
|
||||
loadFromServer,
|
||||
saveToServer,
|
||||
extractEnvironmentSettings,
|
||||
getCurrentEnvironmentSettings,
|
||||
updateCurrentEnvironmentSettings
|
||||
}
|
||||
|
|
@ -0,0 +1,290 @@
|
|||
/**
|
||||
* Application State
|
||||
*
|
||||
* Singleton класс для управления глобальным состоянием приложения.
|
||||
*/
|
||||
|
||||
import { defaultSettings, defaultEnvironmentState } from '../data/defaults.js'
|
||||
import {
|
||||
saveEnvironmentData,
|
||||
loadEnvironmentData,
|
||||
saveSettings,
|
||||
loadSettings
|
||||
} from '../data/storage.js'
|
||||
|
||||
/**
|
||||
* AppState class - manages global application state
|
||||
* Implements Singleton pattern
|
||||
*/
|
||||
class AppState {
|
||||
constructor() {
|
||||
if (AppState.instance) {
|
||||
return AppState.instance
|
||||
}
|
||||
|
||||
// Settings from server
|
||||
this.settings = null
|
||||
|
||||
// Current active environment: 'ift', 'psi', or 'prod'
|
||||
this.currentEnvironment = 'ift'
|
||||
|
||||
// Environment-specific runtime data
|
||||
this.environments = {
|
||||
ift: { ...defaultEnvironmentState },
|
||||
psi: { ...defaultEnvironmentState },
|
||||
prod: { ...defaultEnvironmentState }
|
||||
}
|
||||
|
||||
AppState.instance = this
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current environment
|
||||
* @returns {string} Current environment name
|
||||
*/
|
||||
getCurrentEnvironment() {
|
||||
return this.currentEnvironment
|
||||
}
|
||||
|
||||
/**
|
||||
* Set current environment
|
||||
* @param {string} env - Environment name ('ift', 'psi', 'prod')
|
||||
*/
|
||||
setCurrentEnvironment(env) {
|
||||
if (!['ift', 'psi', 'prod'].includes(env)) {
|
||||
console.error(`Invalid environment: ${env}`)
|
||||
return
|
||||
}
|
||||
|
||||
this.currentEnvironment = env
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current environment state
|
||||
* @returns {object} Current environment state
|
||||
*/
|
||||
getCurrentEnv() {
|
||||
return this.environments[this.currentEnvironment]
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current environment settings
|
||||
* @returns {object} Current environment settings
|
||||
*/
|
||||
getCurrentEnvSettings() {
|
||||
if (!this.settings) {
|
||||
return null
|
||||
}
|
||||
|
||||
return this.settings.environments[this.currentEnvironment]
|
||||
}
|
||||
|
||||
/**
|
||||
* Get environment state by name
|
||||
* @param {string} env - Environment name
|
||||
* @returns {object} Environment state
|
||||
*/
|
||||
getEnvironment(env) {
|
||||
return this.environments[env]
|
||||
}
|
||||
|
||||
/**
|
||||
* Set settings
|
||||
* @param {object} settings - Settings object from server
|
||||
*/
|
||||
setSettings(settings) {
|
||||
this.settings = settings
|
||||
|
||||
// Update current environment from settings
|
||||
if (settings.activeEnvironment) {
|
||||
this.setCurrentEnvironment(settings.activeEnvironment)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update settings
|
||||
* @param {object} updates - Settings updates
|
||||
*/
|
||||
updateSettings(updates) {
|
||||
if (!this.settings) {
|
||||
this.settings = { ...defaultSettings }
|
||||
}
|
||||
|
||||
this.settings = {
|
||||
...this.settings,
|
||||
...updates
|
||||
}
|
||||
|
||||
// Update current environment if changed
|
||||
if (updates.activeEnvironment) {
|
||||
this.setCurrentEnvironment(updates.activeEnvironment)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update environment-specific settings
|
||||
* @param {string} env - Environment name
|
||||
* @param {object} envSettings - Environment settings updates
|
||||
*/
|
||||
updateEnvironmentSettings(env, envSettings) {
|
||||
if (!this.settings) {
|
||||
this.settings = { ...defaultSettings }
|
||||
}
|
||||
|
||||
if (!this.settings.environments) {
|
||||
this.settings.environments = {}
|
||||
}
|
||||
|
||||
this.settings.environments[env] = {
|
||||
...this.settings.environments[env],
|
||||
...envSettings
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set current request for environment
|
||||
* @param {string} env - Environment name
|
||||
* @param {object} request - Request object
|
||||
*/
|
||||
setRequest(env, request) {
|
||||
this.environments[env].currentRequest = request
|
||||
}
|
||||
|
||||
/**
|
||||
* Set current response for environment
|
||||
* @param {string} env - Environment name
|
||||
* @param {object} response - Response object
|
||||
*/
|
||||
setResponse(env, response) {
|
||||
this.environments[env].currentResponse = response
|
||||
}
|
||||
|
||||
/**
|
||||
* Set request metadata
|
||||
* @param {string} env - Environment name
|
||||
* @param {string} requestId - Request ID
|
||||
* @param {string} timestamp - Request timestamp
|
||||
*/
|
||||
setRequestMetadata(env, requestId, timestamp) {
|
||||
this.environments[env].requestId = requestId
|
||||
this.environments[env].requestTimestamp = timestamp
|
||||
}
|
||||
|
||||
/**
|
||||
* Set current answer index
|
||||
* @param {string} env - Environment name
|
||||
* @param {number} index - Answer index
|
||||
*/
|
||||
setCurrentAnswerIndex(env, index) {
|
||||
this.environments[env].currentAnswerIndex = index
|
||||
}
|
||||
|
||||
/**
|
||||
* Set annotations for environment
|
||||
* @param {string} env - Environment name
|
||||
* @param {object} annotations - Annotations object
|
||||
*/
|
||||
setAnnotations(env, annotations) {
|
||||
this.environments[env].annotations = annotations
|
||||
}
|
||||
|
||||
/**
|
||||
* Get annotations for environment
|
||||
* @param {string} env - Environment name
|
||||
* @returns {object} Annotations object
|
||||
*/
|
||||
getAnnotations(env) {
|
||||
return this.environments[env].annotations || {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear environment data
|
||||
* @param {string} env - Environment name
|
||||
*/
|
||||
clearEnvironment(env) {
|
||||
this.environments[env] = { ...defaultEnvironmentState }
|
||||
}
|
||||
|
||||
/**
|
||||
* Save environment data to localStorage
|
||||
* @param {string} env - Environment name
|
||||
*/
|
||||
saveEnvironmentToStorage(env) {
|
||||
const data = this.environments[env]
|
||||
saveEnvironmentData(env, data)
|
||||
}
|
||||
|
||||
/**
|
||||
* Load environment data from localStorage
|
||||
* @param {string} env - Environment name
|
||||
*/
|
||||
loadEnvironmentFromStorage(env) {
|
||||
const data = loadEnvironmentData(env)
|
||||
|
||||
if (data) {
|
||||
this.environments[env] = data
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save settings to localStorage
|
||||
*/
|
||||
saveSettingsToStorage() {
|
||||
if (this.settings) {
|
||||
saveSettings(this.settings)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load settings from localStorage
|
||||
*/
|
||||
loadSettingsFromStorage() {
|
||||
const settings = loadSettings()
|
||||
|
||||
if (settings) {
|
||||
this.setSettings(settings)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all data from localStorage
|
||||
*/
|
||||
loadAllFromStorage() {
|
||||
this.loadSettingsFromStorage()
|
||||
|
||||
const environments = ['ift', 'psi', 'prod']
|
||||
environments.forEach(env => this.loadEnvironmentFromStorage(env))
|
||||
}
|
||||
|
||||
/**
|
||||
* Save all data to localStorage
|
||||
*/
|
||||
saveAllToStorage() {
|
||||
this.saveSettingsToStorage()
|
||||
|
||||
const environments = ['ift', 'psi', 'prod']
|
||||
environments.forEach(env => this.saveEnvironmentToStorage(env))
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset to default state
|
||||
*/
|
||||
reset() {
|
||||
this.settings = null
|
||||
this.currentEnvironment = 'ift'
|
||||
this.environments = {
|
||||
ift: { ...defaultEnvironmentState },
|
||||
psi: { ...defaultEnvironmentState },
|
||||
prod: { ...defaultEnvironmentState }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create singleton instance
|
||||
const appState = new AppState()
|
||||
|
||||
// Export singleton instance as default export
|
||||
export default appState
|
||||
|
||||
// Export class for testing purposes
|
||||
export { AppState }
|
||||
Loading…
Reference in New Issue