refactored api uses and constants
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"y_min": -80,
|
"y_min": -80,
|
||||||
"y_max": 40,
|
"y_max": 40,
|
||||||
"show_phase": false
|
"show_phase": true
|
||||||
}
|
}
|
||||||
@ -4,6 +4,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { setButtonLoading } from './utils.js';
|
import { setButtonLoading } from './utils.js';
|
||||||
|
import { apiGet, apiPost } from './api-client.js';
|
||||||
|
import { API, TIMING, NOTIFICATION_TYPES } from './constants.js';
|
||||||
|
|
||||||
|
const { SUCCESS, ERROR } = NOTIFICATION_TYPES;
|
||||||
|
|
||||||
export class AcquisitionManager {
|
export class AcquisitionManager {
|
||||||
constructor(notifications) {
|
constructor(notifications) {
|
||||||
@ -44,8 +48,8 @@ export class AcquisitionManager {
|
|||||||
// Initial status update
|
// Initial status update
|
||||||
this.updateStatus();
|
this.updateStatus();
|
||||||
|
|
||||||
// Poll status every 2 seconds
|
// Poll status periodically
|
||||||
this.statusInterval = setInterval(this.updateStatus, 2000);
|
this.statusInterval = setInterval(this.updateStatus, TIMING.STATUS_POLL_INTERVAL);
|
||||||
|
|
||||||
this.isInitialized = true;
|
this.isInitialized = true;
|
||||||
console.log('AcquisitionManager initialized');
|
console.log('AcquisitionManager initialized');
|
||||||
@ -55,22 +59,17 @@ export class AcquisitionManager {
|
|||||||
try {
|
try {
|
||||||
const originalState = setButtonLoading(this.elements.startBtn, true);
|
const originalState = setButtonLoading(this.elements.startBtn, true);
|
||||||
|
|
||||||
const response = await fetch('/api/v1/acquisition/start', {
|
const result = await apiPost(API.ACQUISITION.START);
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' }
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = await response.json();
|
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
this.notifications.show({type: 'success', title: 'Acquisition Started', message: result.message});
|
this.notifications.show({ type: SUCCESS, title: 'Acquisition Started', message: result.message });
|
||||||
await this.updateStatus();
|
await this.updateStatus();
|
||||||
} else {
|
} else {
|
||||||
this.notifications.show({type: 'error', title: 'Start Failed', message: result.error || 'Failed to start acquisition'});
|
this.notifications.show({ type: ERROR, title: 'Start Failed', message: result.error || 'Failed to start acquisition' });
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error starting acquisition:', error);
|
console.error('Error starting acquisition:', error);
|
||||||
this.notifications.show({type: 'error', title: 'Start Failed', message: 'Failed to start acquisition'});
|
this.notifications.show({ type: ERROR, title: 'Start Failed', message: 'Failed to start acquisition' });
|
||||||
} finally {
|
} finally {
|
||||||
setButtonLoading(this.elements.startBtn, false, originalState);
|
setButtonLoading(this.elements.startBtn, false, originalState);
|
||||||
}
|
}
|
||||||
@ -80,22 +79,17 @@ export class AcquisitionManager {
|
|||||||
try {
|
try {
|
||||||
const originalState = setButtonLoading(this.elements.stopBtn, true);
|
const originalState = setButtonLoading(this.elements.stopBtn, true);
|
||||||
|
|
||||||
const response = await fetch('/api/v1/acquisition/stop', {
|
const result = await apiPost(API.ACQUISITION.STOP);
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' }
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = await response.json();
|
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
this.notifications.show({type: 'success', title: 'Acquisition Stopped', message: result.message});
|
this.notifications.show({ type: SUCCESS, title: 'Acquisition Stopped', message: result.message });
|
||||||
await this.updateStatus();
|
await this.updateStatus();
|
||||||
} else {
|
} else {
|
||||||
this.notifications.show({type: 'error', title: 'Stop Failed', message: result.error || 'Failed to stop acquisition'});
|
this.notifications.show({ type: ERROR, title: 'Stop Failed', message: result.error || 'Failed to stop acquisition' });
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error stopping acquisition:', error);
|
console.error('Error stopping acquisition:', error);
|
||||||
this.notifications.show({type: 'error', title: 'Stop Failed', message: 'Failed to stop acquisition'});
|
this.notifications.show({ type: ERROR, title: 'Stop Failed', message: 'Failed to stop acquisition' });
|
||||||
} finally {
|
} finally {
|
||||||
setButtonLoading(this.elements.stopBtn, false, originalState);
|
setButtonLoading(this.elements.stopBtn, false, originalState);
|
||||||
}
|
}
|
||||||
@ -105,22 +99,17 @@ export class AcquisitionManager {
|
|||||||
try {
|
try {
|
||||||
const originalState = setButtonLoading(this.elements.singleSweepBtn, true);
|
const originalState = setButtonLoading(this.elements.singleSweepBtn, true);
|
||||||
|
|
||||||
const response = await fetch('/api/v1/acquisition/single-sweep', {
|
const result = await apiPost(API.ACQUISITION.SINGLE);
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' }
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = await response.json();
|
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
this.notifications.show({type: 'success', title: 'Single Sweep', message: result.message});
|
this.notifications.show({ type: SUCCESS, title: 'Single Sweep', message: result.message });
|
||||||
await this.updateStatus();
|
await this.updateStatus();
|
||||||
} else {
|
} else {
|
||||||
this.notifications.show({type: 'error', title: 'Single Sweep Failed', message: result.error || 'Failed to trigger single sweep'});
|
this.notifications.show({ type: ERROR, title: 'Single Sweep Failed', message: result.error || 'Failed to trigger single sweep' });
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error triggering single sweep:', error);
|
console.error('Error triggering single sweep:', error);
|
||||||
this.notifications.show({type: 'error', title: 'Single Sweep Failed', message: 'Failed to trigger single sweep'});
|
this.notifications.show({ type: ERROR, title: 'Single Sweep Failed', message: 'Failed to trigger single sweep' });
|
||||||
} finally {
|
} finally {
|
||||||
setButtonLoading(this.elements.singleSweepBtn, false, originalState);
|
setButtonLoading(this.elements.singleSweepBtn, false, originalState);
|
||||||
}
|
}
|
||||||
@ -128,8 +117,7 @@ export class AcquisitionManager {
|
|||||||
|
|
||||||
async updateStatus() {
|
async updateStatus() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/v1/acquisition/status');
|
const status = await apiGet(API.ACQUISITION.STATUS);
|
||||||
const status = await response.json();
|
|
||||||
|
|
||||||
this.currentStatus = status;
|
this.currentStatus = status;
|
||||||
this.updateUI(status);
|
this.updateUI(status);
|
||||||
|
|||||||
94
vna_system/web_ui/static/js/modules/api-client.js
Normal file
94
vna_system/web_ui/static/js/modules/api-client.js
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
/**
|
||||||
|
* API Client
|
||||||
|
* Centralized API request handling with consistent error handling
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default fetch options
|
||||||
|
*/
|
||||||
|
const DEFAULT_OPTIONS = {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base API request wrapper
|
||||||
|
* @param {string} url - API endpoint URL
|
||||||
|
* @param {Object} options - Fetch options
|
||||||
|
* @returns {Promise<any>} Response data
|
||||||
|
*/
|
||||||
|
async function apiRequest(url, options = {}) {
|
||||||
|
const response = await fetch(url, {
|
||||||
|
...DEFAULT_OPTIONS,
|
||||||
|
...options,
|
||||||
|
headers: {
|
||||||
|
...DEFAULT_OPTIONS.headers,
|
||||||
|
...options.headers
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorText = await response.text().catch(() => response.statusText);
|
||||||
|
const error = new Error(`HTTP ${response.status}: ${errorText}`);
|
||||||
|
error.status = response.status;
|
||||||
|
error.body = errorText;
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if response has content
|
||||||
|
const contentType = response.headers.get('content-type');
|
||||||
|
if (contentType && contentType.includes('application/json')) {
|
||||||
|
return await response.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
return await response.text();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET request
|
||||||
|
* @param {string} url - API endpoint URL
|
||||||
|
* @returns {Promise<any>} Response data
|
||||||
|
*/
|
||||||
|
export async function apiGet(url) {
|
||||||
|
return await apiRequest(url, { method: 'GET' });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST request
|
||||||
|
* @param {string} url - API endpoint URL
|
||||||
|
* @param {Object} data - Request body data
|
||||||
|
* @returns {Promise<any>} Response data
|
||||||
|
*/
|
||||||
|
export async function apiPost(url, data = null) {
|
||||||
|
const options = { method: 'POST' };
|
||||||
|
if (data !== null) {
|
||||||
|
options.body = JSON.stringify(data);
|
||||||
|
}
|
||||||
|
return await apiRequest(url, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DELETE request
|
||||||
|
* @param {string} url - API endpoint URL
|
||||||
|
* @returns {Promise<any>} Response data
|
||||||
|
*/
|
||||||
|
export async function apiDelete(url) {
|
||||||
|
return await apiRequest(url, { method: 'DELETE' });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build URL with query parameters
|
||||||
|
* @param {string} baseUrl - Base URL
|
||||||
|
* @param {Object} params - Query parameters
|
||||||
|
* @returns {string} URL with query string
|
||||||
|
*/
|
||||||
|
export function buildUrl(baseUrl, params = {}) {
|
||||||
|
const url = new URL(baseUrl, window.location.origin);
|
||||||
|
Object.entries(params).forEach(([key, value]) => {
|
||||||
|
if (value !== null && value !== undefined) {
|
||||||
|
url.searchParams.append(key, value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return url.toString();
|
||||||
|
}
|
||||||
140
vna_system/web_ui/static/js/modules/constants.js
Normal file
140
vna_system/web_ui/static/js/modules/constants.js
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/**
|
||||||
|
* Application Constants
|
||||||
|
* Centralized configuration values
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Timing constants (milliseconds)
|
||||||
|
export const TIMING = {
|
||||||
|
DEBOUNCE_DEFAULT: 300,
|
||||||
|
DEBOUNCE_SETTINGS: 300,
|
||||||
|
DEBOUNCE_RESIZE: 300,
|
||||||
|
DEBOUNCE_PRESET: 300,
|
||||||
|
DEBOUNCE_CALIBRATION: 400,
|
||||||
|
DEBOUNCE_REFERENCE: 500,
|
||||||
|
DEBOUNCE_DOWNLOAD: 600,
|
||||||
|
|
||||||
|
BUTTON_FEEDBACK: 1000,
|
||||||
|
|
||||||
|
STATUS_POLL_INTERVAL: 2000,
|
||||||
|
|
||||||
|
RECONNECT_BASE: 3000,
|
||||||
|
RECONNECT_MAX: 30000,
|
||||||
|
|
||||||
|
CONNECTION_TIMEOUT: 5000,
|
||||||
|
PING_INTERVAL: 30000,
|
||||||
|
|
||||||
|
NOTIFICATION_SUCCESS: 3000,
|
||||||
|
NOTIFICATION_ERROR: 7000,
|
||||||
|
NOTIFICATION_WARNING: 5000,
|
||||||
|
NOTIFICATION_INFO: 4000,
|
||||||
|
NOTIFICATION_ANIMATION: 300,
|
||||||
|
|
||||||
|
FULLSCREEN_RESIZE_DELAY: 200,
|
||||||
|
FULLSCREEN_EXIT_DELAY: 100,
|
||||||
|
|
||||||
|
CHART_ANIMATION_DELAY: 50,
|
||||||
|
ICON_INIT_DELAY: 10
|
||||||
|
};
|
||||||
|
|
||||||
|
// Size limits
|
||||||
|
export const LIMITS = {
|
||||||
|
MAX_NOTIFICATIONS: 5,
|
||||||
|
MAX_RECONNECT_ATTEMPTS: 10,
|
||||||
|
MAX_QUEUE_SIZE: 100,
|
||||||
|
MAX_DATA_POINTS: 1000,
|
||||||
|
MAX_CHARTS_SAVED: 10,
|
||||||
|
CHART_DATA_HISTORY: 100,
|
||||||
|
|
||||||
|
STORAGE_CLEANUP_DAYS: 7,
|
||||||
|
MESSAGE_RATE_WINDOW: 1000,
|
||||||
|
|
||||||
|
NOTIFICATION_DEDUPE_WINDOW: 2000,
|
||||||
|
NOTIFICATION_CLEANUP_AGE: 5000
|
||||||
|
};
|
||||||
|
|
||||||
|
// API endpoints
|
||||||
|
const API_BASE = '/api/v1';
|
||||||
|
|
||||||
|
export const API = {
|
||||||
|
BASE: API_BASE,
|
||||||
|
|
||||||
|
ACQUISITION: {
|
||||||
|
START: `${API_BASE}/acquisition/start`,
|
||||||
|
STOP: `${API_BASE}/acquisition/stop`,
|
||||||
|
SINGLE: `${API_BASE}/acquisition/single-sweep`,
|
||||||
|
STATUS: `${API_BASE}/acquisition/status`
|
||||||
|
},
|
||||||
|
|
||||||
|
SETTINGS: {
|
||||||
|
PRESETS: `${API_BASE}/settings/presets`,
|
||||||
|
PRESET_SET: `${API_BASE}/settings/preset/set`,
|
||||||
|
STATUS: `${API_BASE}/settings/status`,
|
||||||
|
|
||||||
|
CALIBRATIONS: `${API_BASE}/settings/calibrations`,
|
||||||
|
CALIBRATION_START: `${API_BASE}/settings/calibration/start`,
|
||||||
|
CALIBRATION_SAVE: `${API_BASE}/settings/calibration/save`,
|
||||||
|
CALIBRATION_SET: `${API_BASE}/settings/calibration/set`,
|
||||||
|
CALIBRATION_ADD_STANDARD: `${API_BASE}/settings/calibration/add-standard`,
|
||||||
|
CALIBRATION_STANDARDS_PLOTS: (name) => `${API_BASE}/settings/calibration/${encodeURIComponent(name)}/standards-plots`,
|
||||||
|
|
||||||
|
WORKING_CALIBRATION: `${API_BASE}/settings/working-calibration`,
|
||||||
|
WORKING_CALIBRATION_PLOTS: `${API_BASE}/settings/working-calibration/standards-plots`,
|
||||||
|
|
||||||
|
REFERENCES: `${API_BASE}/settings/references`,
|
||||||
|
REFERENCE_CREATE: `${API_BASE}/settings/reference/create`,
|
||||||
|
REFERENCE_SET: `${API_BASE}/settings/reference/set`,
|
||||||
|
REFERENCE_CURRENT: `${API_BASE}/settings/reference/current`,
|
||||||
|
REFERENCE_ITEM: (name) => `${API_BASE}/settings/reference/${encodeURIComponent(name)}`
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Storage keys
|
||||||
|
export const STORAGE_KEYS = {
|
||||||
|
PREFERENCES: 'preferences',
|
||||||
|
CHART_DATA: 'chart_data',
|
||||||
|
SESSION: 'session_data',
|
||||||
|
DEBUG: 'debug_info'
|
||||||
|
};
|
||||||
|
|
||||||
|
// WebSocket events
|
||||||
|
export const WS_EVENTS = {
|
||||||
|
CONNECTING: 'connecting',
|
||||||
|
CONNECTED: 'connected',
|
||||||
|
DISCONNECTED: 'disconnected',
|
||||||
|
DATA: 'data',
|
||||||
|
PROCESSOR_RESULT: 'processor_result',
|
||||||
|
PROCESSOR_HISTORY: 'processor_history',
|
||||||
|
ERROR: 'error'
|
||||||
|
};
|
||||||
|
|
||||||
|
// WebSocket message types
|
||||||
|
export const WS_MESSAGE_TYPES = {
|
||||||
|
PING: 'ping',
|
||||||
|
PONG: 'pong',
|
||||||
|
RECALCULATE: 'recalculate',
|
||||||
|
GET_HISTORY: 'get_history',
|
||||||
|
PROCESSOR_RESULT: 'processor_result',
|
||||||
|
PROCESSOR_HISTORY: 'processor_history',
|
||||||
|
ERROR: 'error'
|
||||||
|
};
|
||||||
|
|
||||||
|
// Notification types
|
||||||
|
export const NOTIFICATION_TYPES = {
|
||||||
|
SUCCESS: 'success',
|
||||||
|
ERROR: 'error',
|
||||||
|
WARNING: 'warning',
|
||||||
|
INFO: 'info'
|
||||||
|
};
|
||||||
|
|
||||||
|
// Chart update queue
|
||||||
|
export const CHART = {
|
||||||
|
UPDATE_INTERVAL: 100,
|
||||||
|
MAX_DATA_POINTS: 1000,
|
||||||
|
ANIMATION_ENABLED: true
|
||||||
|
};
|
||||||
|
|
||||||
|
// Calibration standards by mode
|
||||||
|
export const CALIBRATION_STANDARDS = {
|
||||||
|
S11: ['open', 'short', 'load'],
|
||||||
|
S21: ['through']
|
||||||
|
};
|
||||||
@ -13,6 +13,10 @@ import {
|
|||||||
downloadPlotlyImage,
|
downloadPlotlyImage,
|
||||||
cleanupPlotly
|
cleanupPlotly
|
||||||
} from './plotly-utils.js';
|
} from './plotly-utils.js';
|
||||||
|
import { apiGet, buildUrl } from './api-client.js';
|
||||||
|
import { API, TIMING, NOTIFICATION_TYPES } from './constants.js';
|
||||||
|
|
||||||
|
const { SUCCESS, ERROR, WARNING } = NOTIFICATION_TYPES;
|
||||||
|
|
||||||
export class SettingsManager {
|
export class SettingsManager {
|
||||||
constructor(notifications, websocket, acquisition) {
|
constructor(notifications, websocket, acquisition) {
|
||||||
@ -48,7 +52,7 @@ export class SettingsManager {
|
|||||||
console.log('Settings Manager initialized');
|
console.log('Settings Manager initialized');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Settings Manager init failed:', err);
|
console.error('Settings Manager init failed:', err);
|
||||||
this.notify('error', 'Settings Error', 'Failed to initialize settings');
|
this.notify(ERROR, 'Settings Error', 'Failed to initialize settings');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,9 +140,7 @@ export class SettingsManager {
|
|||||||
|
|
||||||
async loadStatus() {
|
async loadStatus() {
|
||||||
try {
|
try {
|
||||||
const r = await fetch('/api/v1/settings/status');
|
const status = await apiGet(API.SETTINGS.STATUS);
|
||||||
if (!r.ok) throw new Error(`HTTP ${r.status}`);
|
|
||||||
const status = await r.json();
|
|
||||||
this.updateStatusDisplay(status);
|
this.updateStatusDisplay(status);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Status load failed:', e);
|
console.error('Status load failed:', e);
|
||||||
@ -167,19 +169,19 @@ export class SettingsManager {
|
|||||||
try {
|
try {
|
||||||
ButtonState.set(this.elements.viewPlotsBtn, { state: 'loading', icon: 'loader', text: 'Loading...' });
|
ButtonState.set(this.elements.viewPlotsBtn, { state: 'loading', icon: 'loader', text: 'Loading...' });
|
||||||
|
|
||||||
const url = `/api/v1/settings/calibration/${encodeURIComponent(name)}/standards-plots?preset_filename=${encodeURIComponent(preset.filename)}`;
|
const url = buildUrl(API.SETTINGS.CALIBRATION_STANDARDS_PLOTS(name), {
|
||||||
const r = await fetch(url);
|
preset_filename: preset.filename
|
||||||
if (!r.ok) throw new Error(`HTTP ${r.status}`);
|
});
|
||||||
const plotsData = await r.json();
|
const plotsData = await apiGet(url);
|
||||||
|
|
||||||
this.showPlotsModal(plotsData);
|
this.showPlotsModal(plotsData);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Load plots failed:', e);
|
console.error('Load plots failed:', e);
|
||||||
this.notify('error', 'Plots Error', 'Failed to load calibration plots');
|
this.notify(ERROR, 'Plots Error', 'Failed to load calibration plots');
|
||||||
} finally {
|
} finally {
|
||||||
ButtonState.set(this.elements.viewPlotsBtn, { state: 'normal', icon: 'bar-chart-3', text: 'View Plots' });
|
ButtonState.set(this.elements.viewPlotsBtn, { state: 'normal', icon: 'bar-chart-3', text: 'View Plots' });
|
||||||
}
|
}
|
||||||
}, 300);
|
}, TIMING.DEBOUNCE_CALIBRATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleViewCurrentPlots() {
|
async handleViewCurrentPlots() {
|
||||||
@ -190,23 +192,19 @@ export class SettingsManager {
|
|||||||
try {
|
try {
|
||||||
ButtonState.set(this.elements.viewCurrentPlotsBtn, { state: 'loading', icon: 'loader', text: 'Loading...' });
|
ButtonState.set(this.elements.viewCurrentPlotsBtn, { state: 'loading', icon: 'loader', text: 'Loading...' });
|
||||||
|
|
||||||
const r = await fetch('/api/v1/settings/working-calibration/standards-plots');
|
const plotsData = await apiGet(API.SETTINGS.WORKING_CALIBRATION_PLOTS);
|
||||||
if (!r.ok) {
|
|
||||||
if (r.status === 404) {
|
|
||||||
this.notify('warning', 'No Data', 'No working calibration or standards available to plot');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new Error(`HTTP ${r.status}`);
|
|
||||||
}
|
|
||||||
const plotsData = await r.json();
|
|
||||||
this.showPlotsModal(plotsData);
|
this.showPlotsModal(plotsData);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
if (e.status === 404) {
|
||||||
|
this.notify(WARNING, 'No Data', 'No working calibration or standards available to plot');
|
||||||
|
} else {
|
||||||
console.error('Load current plots failed:', e);
|
console.error('Load current plots failed:', e);
|
||||||
this.notify('error', 'Plots Error', 'Failed to load current calibration plots');
|
this.notify(ERROR, 'Plots Error', 'Failed to load current calibration plots');
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
ButtonState.set(this.elements.viewCurrentPlotsBtn, { state: 'normal', icon: 'bar-chart-3', text: 'View Current Plots' });
|
ButtonState.set(this.elements.viewCurrentPlotsBtn, { state: 'normal', icon: 'bar-chart-3', text: 'View Current Plots' });
|
||||||
}
|
}
|
||||||
}, 300);
|
}, TIMING.DEBOUNCE_CALIBRATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
showPlotsModal(plotsData) {
|
showPlotsModal(plotsData) {
|
||||||
@ -368,7 +366,7 @@ export class SettingsManager {
|
|||||||
const downloadAllBtn = modal.querySelector('#downloadAllBtn');
|
const downloadAllBtn = modal.querySelector('#downloadAllBtn');
|
||||||
if (downloadAllBtn) {
|
if (downloadAllBtn) {
|
||||||
downloadAllBtn.addEventListener('click', () =>
|
downloadAllBtn.addEventListener('click', () =>
|
||||||
this.debouncer.debounce('download-all', () => this.downloadAllCalibrationData(), 600)
|
this.debouncer.debounce('download-all', () => this.downloadAllCalibrationData(), TIMING.DEBOUNCE_DOWNLOAD)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,10 +405,10 @@ export class SettingsManager {
|
|||||||
const data = this.prepareCalibrationDownloadData(standardName);
|
const data = this.prepareCalibrationDownloadData(standardName);
|
||||||
downloadJSON(data, `${base}_data.json`);
|
downloadJSON(data, `${base}_data.json`);
|
||||||
|
|
||||||
this.notify('success', 'Download Complete', `Downloaded ${standardName.toUpperCase()} standard plot and data`);
|
this.notify(SUCCESS, 'Download Complete', `Downloaded ${standardName.toUpperCase()} standard plot and data`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Download standard failed:', e);
|
console.error('Download standard failed:', e);
|
||||||
this.notify('error', 'Download Failed', 'Failed to download calibration data');
|
this.notify(ERROR, 'Download Failed', 'Failed to download calibration data');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,10 +434,10 @@ export class SettingsManager {
|
|||||||
|
|
||||||
downloadJSON(complete, `${base}.json`);
|
downloadJSON(complete, `${base}.json`);
|
||||||
|
|
||||||
this.notify('success', 'Complete Download', `Downloaded complete calibration data for ${calibrationName}`);
|
this.notify(SUCCESS, 'Complete Download', `Downloaded complete calibration data for ${calibrationName}`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Download all failed:', e);
|
console.error('Download all failed:', e);
|
||||||
this.notify('error', 'Download Failed', 'Failed to download complete calibration data');
|
this.notify(ERROR, 'Download Failed', 'Failed to download complete calibration data');
|
||||||
} finally {
|
} finally {
|
||||||
const btn = this.elements.downloadAllBtn;
|
const btn = this.elements.downloadAllBtn;
|
||||||
if (btn) ButtonState.set(btn, { state: 'normal', icon: 'download-cloud', text: 'Download All' });
|
if (btn) ButtonState.set(btn, { state: 'normal', icon: 'download-cloud', text: 'Download All' });
|
||||||
|
|||||||
@ -4,6 +4,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Debouncer, RequestGuard, ButtonState } from '../utils.js';
|
import { Debouncer, RequestGuard, ButtonState } from '../utils.js';
|
||||||
|
import { apiGet, apiPost, buildUrl } from '../api-client.js';
|
||||||
|
import { API, TIMING, CALIBRATION_STANDARDS, NOTIFICATION_TYPES } from '../constants.js';
|
||||||
|
|
||||||
|
const { SUCCESS, ERROR, INFO } = NOTIFICATION_TYPES;
|
||||||
|
|
||||||
export class CalibrationManager {
|
export class CalibrationManager {
|
||||||
constructor(notifications) {
|
constructor(notifications) {
|
||||||
@ -57,9 +61,7 @@ export class CalibrationManager {
|
|||||||
|
|
||||||
async loadWorkingCalibration() {
|
async loadWorkingCalibration() {
|
||||||
try {
|
try {
|
||||||
const r = await fetch('/api/v1/settings/working-calibration');
|
const working = await apiGet(API.SETTINGS.WORKING_CALIBRATION);
|
||||||
if (!r.ok) throw new Error(`HTTP ${r.status}`);
|
|
||||||
const working = await r.json();
|
|
||||||
this.updateWorking(working);
|
this.updateWorking(working);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Working calibration load failed:', e);
|
console.error('Working calibration load failed:', e);
|
||||||
@ -69,9 +71,10 @@ export class CalibrationManager {
|
|||||||
async loadCalibrations() {
|
async loadCalibrations() {
|
||||||
if (!this.currentPreset) return;
|
if (!this.currentPreset) return;
|
||||||
try {
|
try {
|
||||||
const r = await fetch(`/api/v1/settings/calibrations?preset_filename=${encodeURIComponent(this.currentPreset.filename)}`);
|
const url = buildUrl(API.SETTINGS.CALIBRATIONS, {
|
||||||
if (!r.ok) throw new Error(`HTTP ${r.status}`);
|
preset_filename: this.currentPreset.filename
|
||||||
const calibrations = await r.json();
|
});
|
||||||
|
const calibrations = await apiGet(url);
|
||||||
this.populateDropdown(calibrations);
|
this.populateDropdown(calibrations);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Calibrations load failed:', e);
|
console.error('Calibrations load failed:', e);
|
||||||
@ -184,10 +187,9 @@ export class CalibrationManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getStandardsForMode() {
|
getStandardsForMode() {
|
||||||
if (!this.currentPreset) return [];
|
if (!this.currentPreset || !this.currentPreset.mode) return [];
|
||||||
if (this.currentPreset.mode === 's11') return ['open', 'short', 'load'];
|
const modeKey = this.currentPreset.mode.toUpperCase();
|
||||||
if (this.currentPreset.mode === 's21') return ['through'];
|
return CALIBRATION_STANDARDS[modeKey] || [];
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleCalibrationChange() {
|
handleCalibrationChange() {
|
||||||
@ -204,24 +206,20 @@ export class CalibrationManager {
|
|||||||
try {
|
try {
|
||||||
ButtonState.set(this.elements.startCalibrationBtn, { state: 'loading', icon: 'loader', text: 'Starting...' });
|
ButtonState.set(this.elements.startCalibrationBtn, { state: 'loading', icon: 'loader', text: 'Starting...' });
|
||||||
|
|
||||||
const r = await fetch('/api/v1/settings/calibration/start', {
|
const result = await apiPost(API.SETTINGS.CALIBRATION_START, {
|
||||||
method: 'POST',
|
preset_filename: this.currentPreset.filename
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({ preset_filename: this.currentPreset.filename })
|
|
||||||
});
|
});
|
||||||
if (!r.ok) throw new Error(`HTTP ${r.status}`);
|
|
||||||
const result = await r.json();
|
|
||||||
|
|
||||||
this.notify('info', 'Calibration Started', `Started calibration for ${result.preset}`);
|
this.notify(INFO, 'Calibration Started', `Started calibration for ${result.preset}`);
|
||||||
|
|
||||||
await this.loadWorkingCalibration();
|
await this.loadWorkingCalibration();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Start calibration failed:', e);
|
console.error('Start calibration failed:', e);
|
||||||
this.notify('error', 'Calibration Error', 'Failed to start calibration');
|
this.notify(ERROR, 'Calibration Error', 'Failed to start calibration');
|
||||||
} finally {
|
} finally {
|
||||||
ButtonState.set(this.elements.startCalibrationBtn, { state: 'normal', icon: 'play', text: 'Start Calibration' });
|
ButtonState.set(this.elements.startCalibrationBtn, { state: 'normal', icon: 'play', text: 'Start Calibration' });
|
||||||
}
|
}
|
||||||
}), 400
|
}), TIMING.DEBOUNCE_CALIBRATION
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,27 +235,20 @@ export class CalibrationManager {
|
|||||||
const btn = document.querySelector(`[data-standard="${standard}"]`);
|
const btn = document.querySelector(`[data-standard="${standard}"]`);
|
||||||
ButtonState.set(btn, { state: 'loading', icon: 'upload', text: 'Capturing...' });
|
ButtonState.set(btn, { state: 'loading', icon: 'upload', text: 'Capturing...' });
|
||||||
|
|
||||||
this.notify('info', 'Capturing Standard', `Capturing ${standard.toUpperCase()} standard...`);
|
this.notify(INFO, 'Capturing Standard', `Capturing ${standard.toUpperCase()} standard...`);
|
||||||
|
|
||||||
const r = await fetch('/api/v1/settings/calibration/add-standard', {
|
const result = await apiPost(API.SETTINGS.CALIBRATION_ADD_STANDARD, { standard });
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({ standard })
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!r.ok) throw new Error(`HTTP ${r.status}`);
|
this.notify(SUCCESS, 'Standard Captured', result.message);
|
||||||
const result = await r.json();
|
|
||||||
|
|
||||||
this.notify('success', 'Standard Captured', result.message);
|
|
||||||
|
|
||||||
this.resetCaptureState();
|
this.resetCaptureState();
|
||||||
await this.loadWorkingCalibration();
|
await this.loadWorkingCalibration();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Capture standard failed:', e);
|
console.error('Capture standard failed:', e);
|
||||||
this.notify('error', 'Calibration Error', 'Failed to capture calibration standard');
|
this.notify(ERROR, 'Calibration Error', 'Failed to capture calibration standard');
|
||||||
this.resetCaptureState(standard);
|
this.resetCaptureState(standard);
|
||||||
}
|
}
|
||||||
}), 500
|
}), TIMING.DEBOUNCE_CALIBRATION
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,15 +261,9 @@ export class CalibrationManager {
|
|||||||
try {
|
try {
|
||||||
ButtonState.set(this.elements.saveCalibrationBtn, { state: 'loading', icon: 'loader', text: 'Saving...' });
|
ButtonState.set(this.elements.saveCalibrationBtn, { state: 'loading', icon: 'loader', text: 'Saving...' });
|
||||||
|
|
||||||
const r = await fetch('/api/v1/settings/calibration/save', {
|
const result = await apiPost(API.SETTINGS.CALIBRATION_SAVE, { name });
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({ name })
|
|
||||||
});
|
|
||||||
if (!r.ok) throw new Error(`HTTP ${r.status}`);
|
|
||||||
const result = await r.json();
|
|
||||||
|
|
||||||
this.notify('success', 'Calibration Saved', result.message);
|
this.notify(SUCCESS, 'Calibration Saved', result.message);
|
||||||
|
|
||||||
this.hideSteps();
|
this.hideSteps();
|
||||||
this.elements.calibrationNameInput.value = '';
|
this.elements.calibrationNameInput.value = '';
|
||||||
@ -291,11 +276,11 @@ export class CalibrationManager {
|
|||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Save calibration failed:', e);
|
console.error('Save calibration failed:', e);
|
||||||
this.notify('error', 'Calibration Error', 'Failed to save calibration');
|
this.notify(ERROR, 'Calibration Error', 'Failed to save calibration');
|
||||||
} finally {
|
} finally {
|
||||||
ButtonState.set(this.elements.saveCalibrationBtn, { state: 'disabled', icon: 'save', text: 'Save Calibration' });
|
ButtonState.set(this.elements.saveCalibrationBtn, { state: 'disabled', icon: 'save', text: 'Save Calibration' });
|
||||||
}
|
}
|
||||||
}), 400
|
}), TIMING.DEBOUNCE_CALIBRATION
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,26 +293,23 @@ export class CalibrationManager {
|
|||||||
try {
|
try {
|
||||||
ButtonState.set(this.elements.setCalibrationBtn, { state: 'loading', icon: 'loader', text: 'Setting...' });
|
ButtonState.set(this.elements.setCalibrationBtn, { state: 'loading', icon: 'loader', text: 'Setting...' });
|
||||||
|
|
||||||
const r = await fetch('/api/v1/settings/calibration/set', {
|
const result = await apiPost(API.SETTINGS.CALIBRATION_SET, {
|
||||||
method: 'POST',
|
name,
|
||||||
headers: { 'Content-Type': 'application/json' },
|
preset_filename: this.currentPreset.filename
|
||||||
body: JSON.stringify({ name, preset_filename: this.currentPreset.filename })
|
|
||||||
});
|
});
|
||||||
if (!r.ok) throw new Error(`HTTP ${r.status}`);
|
|
||||||
const result = await r.json();
|
|
||||||
|
|
||||||
this.notify('success', 'Calibration Set', result.message);
|
this.notify(SUCCESS, 'Calibration Set', result.message);
|
||||||
|
|
||||||
if (this.onCalibrationSet) {
|
if (this.onCalibrationSet) {
|
||||||
await this.onCalibrationSet();
|
await this.onCalibrationSet();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Set calibration failed:', e);
|
console.error('Set calibration failed:', e);
|
||||||
this.notify('error', 'Calibration Error', 'Failed to set active calibration');
|
this.notify(ERROR, 'Calibration Error', 'Failed to set active calibration');
|
||||||
} finally {
|
} finally {
|
||||||
ButtonState.set(this.elements.setCalibrationBtn, { state: 'normal', icon: 'check', text: 'Set Active' });
|
ButtonState.set(this.elements.setCalibrationBtn, { state: 'normal', icon: 'check', text: 'Set Active' });
|
||||||
}
|
}
|
||||||
}), 300
|
}), TIMING.DEBOUNCE_CALIBRATION
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Debouncer, RequestGuard, ButtonState } from '../utils.js';
|
import { Debouncer, RequestGuard, ButtonState } from '../utils.js';
|
||||||
|
import { apiGet, apiPost } from '../api-client.js';
|
||||||
|
import { API, TIMING } from '../constants.js';
|
||||||
|
|
||||||
export class PresetManager {
|
export class PresetManager {
|
||||||
constructor(notifications) {
|
constructor(notifications) {
|
||||||
@ -30,9 +32,7 @@ export class PresetManager {
|
|||||||
|
|
||||||
async loadPresets() {
|
async loadPresets() {
|
||||||
try {
|
try {
|
||||||
const r = await fetch('/api/v1/settings/presets');
|
const presets = await apiGet(API.SETTINGS.PRESETS);
|
||||||
if (!r.ok) throw new Error(`HTTP ${r.status}`);
|
|
||||||
const presets = await r.json();
|
|
||||||
this.populateDropdown(presets);
|
this.populateDropdown(presets);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Presets load failed:', e);
|
console.error('Presets load failed:', e);
|
||||||
@ -88,13 +88,7 @@ export class PresetManager {
|
|||||||
try {
|
try {
|
||||||
ButtonState.set(this.elements.setPresetBtn, { state: 'loading', icon: 'loader', text: 'Setting...' });
|
ButtonState.set(this.elements.setPresetBtn, { state: 'loading', icon: 'loader', text: 'Setting...' });
|
||||||
|
|
||||||
const r = await fetch('/api/v1/settings/preset/set', {
|
const result = await apiPost(API.SETTINGS.PRESET_SET, { filename });
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({ filename })
|
|
||||||
});
|
|
||||||
if (!r.ok) throw new Error(`HTTP ${r.status}`);
|
|
||||||
const result = await r.json();
|
|
||||||
|
|
||||||
this.notify('success', 'Preset Set', result.message);
|
this.notify('success', 'Preset Set', result.message);
|
||||||
this.currentPreset = { filename };
|
this.currentPreset = { filename };
|
||||||
@ -108,7 +102,7 @@ export class PresetManager {
|
|||||||
} finally {
|
} finally {
|
||||||
ButtonState.set(this.elements.setPresetBtn, { state: 'normal', icon: 'check', text: 'Set Active' });
|
ButtonState.set(this.elements.setPresetBtn, { state: 'normal', icon: 'check', text: 'Set Active' });
|
||||||
}
|
}
|
||||||
}), 300
|
}), TIMING.DEBOUNCE_PRESET
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Debouncer, RequestGuard, ButtonState } from '../utils.js';
|
import { Debouncer, RequestGuard, ButtonState } from '../utils.js';
|
||||||
|
import { apiGet, apiPost, apiDelete, buildUrl } from '../api-client.js';
|
||||||
|
import { API, TIMING, NOTIFICATION_TYPES } from '../constants.js';
|
||||||
|
|
||||||
|
const { SUCCESS, ERROR, WARNING } = NOTIFICATION_TYPES;
|
||||||
|
|
||||||
export class ReferenceManager {
|
export class ReferenceManager {
|
||||||
constructor(notifications) {
|
constructor(notifications) {
|
||||||
@ -56,13 +60,15 @@ export class ReferenceManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const referencesResponse = await fetch(`/api/v1/settings/references?preset_filename=${encodeURIComponent(this.currentPreset.filename)}`);
|
const referencesUrl = buildUrl(API.SETTINGS.REFERENCES, {
|
||||||
if (!referencesResponse.ok) throw new Error(`HTTP ${referencesResponse.status}`);
|
preset_filename: this.currentPreset.filename
|
||||||
this.availableReferences = await referencesResponse.json();
|
});
|
||||||
|
this.availableReferences = await apiGet(referencesUrl);
|
||||||
|
|
||||||
const currentResponse = await fetch(`/api/v1/settings/reference/current?preset_filename=${encodeURIComponent(this.currentPreset.filename)}`);
|
const currentUrl = buildUrl(API.SETTINGS.REFERENCE_CURRENT, {
|
||||||
if (!currentResponse.ok) throw new Error(`HTTP ${currentResponse.status}`);
|
preset_filename: this.currentPreset.filename
|
||||||
this.currentReference = await currentResponse.json();
|
});
|
||||||
|
this.currentReference = await apiGet(currentUrl);
|
||||||
|
|
||||||
this.renderDropdown(this.availableReferences);
|
this.renderDropdown(this.availableReferences);
|
||||||
this.updateInfo(this.currentReference);
|
this.updateInfo(this.currentReference);
|
||||||
@ -139,7 +145,7 @@ export class ReferenceManager {
|
|||||||
async handleCreateReference() {
|
async handleCreateReference() {
|
||||||
const name = this.elements.referenceNameInput.value.trim();
|
const name = this.elements.referenceNameInput.value.trim();
|
||||||
if (!name) {
|
if (!name) {
|
||||||
this.notify('warning', 'Missing Name', 'Please enter a name for the reference');
|
this.notify(WARNING, 'Missing Name', 'Please enter a name for the reference');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,16 +156,9 @@ export class ReferenceManager {
|
|||||||
try {
|
try {
|
||||||
ButtonState.set(this.elements.createReferenceBtn, { state: 'loading', icon: 'loader', text: 'Creating...' });
|
ButtonState.set(this.elements.createReferenceBtn, { state: 'loading', icon: 'loader', text: 'Creating...' });
|
||||||
|
|
||||||
const response = await fetch('/api/v1/settings/reference/create', {
|
const result = await apiPost(API.SETTINGS.REFERENCE_CREATE, { name, description });
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({ name, description })
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
this.notify(SUCCESS, 'Reference Created', result.message);
|
||||||
const result = await response.json();
|
|
||||||
|
|
||||||
this.notify('success', 'Reference Created', result.message);
|
|
||||||
|
|
||||||
this.elements.referenceNameInput.value = '';
|
this.elements.referenceNameInput.value = '';
|
||||||
this.elements.referenceDescriptionInput.value = '';
|
this.elements.referenceDescriptionInput.value = '';
|
||||||
@ -167,11 +166,11 @@ export class ReferenceManager {
|
|||||||
await this.loadReferences();
|
await this.loadReferences();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Create reference failed:', error);
|
console.error('Create reference failed:', error);
|
||||||
this.notify('error', 'Reference Error', 'Failed to create reference');
|
this.notify(ERROR, 'Reference Error', 'Failed to create reference');
|
||||||
} finally {
|
} finally {
|
||||||
ButtonState.set(this.elements.createReferenceBtn, { state: 'normal', icon: 'target', text: 'Capture Reference' });
|
ButtonState.set(this.elements.createReferenceBtn, { state: 'normal', icon: 'target', text: 'Capture Reference' });
|
||||||
}
|
}
|
||||||
}), 500
|
}), TIMING.DEBOUNCE_REFERENCE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,25 +187,18 @@ export class ReferenceManager {
|
|||||||
try {
|
try {
|
||||||
ButtonState.set(this.elements.setReferenceBtn, { state: 'loading', icon: 'loader', text: 'Setting...' });
|
ButtonState.set(this.elements.setReferenceBtn, { state: 'loading', icon: 'loader', text: 'Setting...' });
|
||||||
|
|
||||||
const response = await fetch('/api/v1/settings/reference/set', {
|
const result = await apiPost(API.SETTINGS.REFERENCE_SET, { name: referenceName });
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({ name: referenceName })
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
this.notify(SUCCESS, 'Reference Set', result.message);
|
||||||
const result = await response.json();
|
|
||||||
|
|
||||||
this.notify('success', 'Reference Set', result.message);
|
|
||||||
|
|
||||||
await this.loadReferences();
|
await this.loadReferences();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Set reference failed:', error);
|
console.error('Set reference failed:', error);
|
||||||
this.notify('error', 'Reference Error', 'Failed to set reference');
|
this.notify(ERROR, 'Reference Error', 'Failed to set reference');
|
||||||
} finally {
|
} finally {
|
||||||
ButtonState.set(this.elements.setReferenceBtn, { state: 'normal', icon: 'check', text: 'Set Active' });
|
ButtonState.set(this.elements.setReferenceBtn, { state: 'normal', icon: 'check', text: 'Set Active' });
|
||||||
}
|
}
|
||||||
}), 400
|
}), TIMING.DEBOUNCE_REFERENCE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,23 +208,18 @@ export class ReferenceManager {
|
|||||||
try {
|
try {
|
||||||
ButtonState.set(this.elements.clearReferenceBtn, { state: 'loading', icon: 'loader', text: 'Clearing...' });
|
ButtonState.set(this.elements.clearReferenceBtn, { state: 'loading', icon: 'loader', text: 'Clearing...' });
|
||||||
|
|
||||||
const response = await fetch('/api/v1/settings/reference/current', {
|
const result = await apiDelete(API.SETTINGS.REFERENCE_CURRENT);
|
||||||
method: 'DELETE'
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
this.notify(SUCCESS, 'Reference Cleared', result.message);
|
||||||
const result = await response.json();
|
|
||||||
|
|
||||||
this.notify('success', 'Reference Cleared', result.message);
|
|
||||||
|
|
||||||
await this.loadReferences();
|
await this.loadReferences();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Clear reference failed:', error);
|
console.error('Clear reference failed:', error);
|
||||||
this.notify('error', 'Reference Error', 'Failed to clear reference');
|
this.notify(ERROR, 'Reference Error', 'Failed to clear reference');
|
||||||
} finally {
|
} finally {
|
||||||
ButtonState.set(this.elements.clearReferenceBtn, { state: 'normal', icon: 'x', text: 'Clear' });
|
ButtonState.set(this.elements.clearReferenceBtn, { state: 'normal', icon: 'x', text: 'Clear' });
|
||||||
}
|
}
|
||||||
}), 400
|
}), TIMING.DEBOUNCE_REFERENCE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,23 +236,18 @@ export class ReferenceManager {
|
|||||||
try {
|
try {
|
||||||
ButtonState.set(this.elements.deleteReferenceBtn, { state: 'loading', icon: 'loader', text: 'Deleting...' });
|
ButtonState.set(this.elements.deleteReferenceBtn, { state: 'loading', icon: 'loader', text: 'Deleting...' });
|
||||||
|
|
||||||
const response = await fetch(`/api/v1/settings/reference/${encodeURIComponent(referenceName)}`, {
|
const result = await apiDelete(API.SETTINGS.REFERENCE_ITEM(referenceName));
|
||||||
method: 'DELETE'
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
this.notify(SUCCESS, 'Reference Deleted', result.message);
|
||||||
const result = await response.json();
|
|
||||||
|
|
||||||
this.notify('success', 'Reference Deleted', result.message);
|
|
||||||
|
|
||||||
await this.loadReferences();
|
await this.loadReferences();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Delete reference failed:', error);
|
console.error('Delete reference failed:', error);
|
||||||
this.notify('error', 'Reference Error', 'Failed to delete reference');
|
this.notify(ERROR, 'Reference Error', 'Failed to delete reference');
|
||||||
} finally {
|
} finally {
|
||||||
ButtonState.set(this.elements.deleteReferenceBtn, { state: 'normal', icon: 'trash-2', text: 'Delete' });
|
ButtonState.set(this.elements.deleteReferenceBtn, { state: 'normal', icon: 'trash-2', text: 'Delete' });
|
||||||
}
|
}
|
||||||
}), 400
|
}), TIMING.DEBOUNCE_REFERENCE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user