The JS-003 and JS-004 rules were only in single-file validation, not in full project validation. Also fixed regex to match functions with parameters (like adminMessages(initialId = null)). Fixed: - messages.js: Added ...data() and currentPage - notifications.js: Added ...data() and currentPage - logs.js: Added noqa (uses baseData pattern with safety check) - settings.js: Added noqa (uses baseData pattern with safety check) - login.js: Added noqa (standalone page, no sidebar) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
225 lines
8.3 KiB
JavaScript
225 lines
8.3 KiB
JavaScript
// static/admin/js/settings.js
|
|
// noqa: JS-003 - Uses ...baseData which is data() with safety check
|
|
|
|
const settingsLog = window.LogConfig?.loggers?.settings || console;
|
|
|
|
function adminSettings() {
|
|
// Get base data with safety check for standalone usage
|
|
const baseData = typeof data === 'function' ? data() : {};
|
|
|
|
return {
|
|
// Inherit base layout functionality from init-alpine.js
|
|
...baseData,
|
|
|
|
// Settings-specific state
|
|
currentPage: 'settings',
|
|
loading: true,
|
|
saving: false,
|
|
error: null,
|
|
successMessage: null,
|
|
activeTab: 'logging',
|
|
logSettings: {
|
|
log_level: 'INFO',
|
|
log_file_max_size_mb: 10,
|
|
log_file_backup_count: 5,
|
|
db_log_retention_days: 30,
|
|
file_logging_enabled: true,
|
|
db_logging_enabled: true
|
|
},
|
|
notificationSettings: {
|
|
email_enabled: true,
|
|
in_app_enabled: true,
|
|
critical_only: false
|
|
},
|
|
shippingSettings: {
|
|
carrier_greco_label_url: 'https://dispatchweb.fr/Tracky/Home/',
|
|
carrier_colissimo_label_url: '',
|
|
carrier_xpresslogistics_label_url: ''
|
|
},
|
|
|
|
async init() {
|
|
try {
|
|
settingsLog.info('=== SETTINGS PAGE INITIALIZING ===');
|
|
await Promise.all([
|
|
this.loadLogSettings(),
|
|
this.loadShippingSettings()
|
|
]);
|
|
} catch (error) {
|
|
settingsLog.error('Init failed:', error);
|
|
this.error = 'Failed to initialize settings page';
|
|
}
|
|
},
|
|
|
|
async refresh() {
|
|
this.error = null;
|
|
this.successMessage = null;
|
|
await Promise.all([
|
|
this.loadLogSettings(),
|
|
this.loadShippingSettings()
|
|
]);
|
|
},
|
|
|
|
async loadLogSettings() {
|
|
this.loading = true;
|
|
this.error = null;
|
|
|
|
try {
|
|
const data = await apiClient.get('/admin/logs/settings');
|
|
this.logSettings = data;
|
|
settingsLog.info('Log settings loaded:', this.logSettings);
|
|
} catch (error) {
|
|
settingsLog.error('Failed to load log settings:', error);
|
|
this.error = error.response?.data?.detail || 'Failed to load log settings';
|
|
} finally {
|
|
this.loading = false;
|
|
}
|
|
},
|
|
|
|
async saveLogSettings() {
|
|
this.saving = true;
|
|
this.error = null;
|
|
this.successMessage = null;
|
|
|
|
try {
|
|
const data = await apiClient.put('/admin/logs/settings', this.logSettings);
|
|
this.successMessage = data.message || 'Log settings saved successfully';
|
|
|
|
// Auto-hide success message after 5 seconds
|
|
setTimeout(() => {
|
|
this.successMessage = null;
|
|
}, 5000);
|
|
|
|
settingsLog.info('Log settings saved successfully');
|
|
} catch (error) {
|
|
settingsLog.error('Failed to save log settings:', error);
|
|
this.error = error.response?.data?.detail || 'Failed to save log settings';
|
|
} finally {
|
|
this.saving = false;
|
|
}
|
|
},
|
|
|
|
async cleanupOldLogs() {
|
|
if (!confirm(`This will delete all logs older than ${this.logSettings.db_log_retention_days} days. Continue?`)) {
|
|
return;
|
|
}
|
|
|
|
this.error = null;
|
|
this.successMessage = null;
|
|
|
|
try {
|
|
const data = await apiClient.delete(
|
|
`/admin/logs/database/cleanup?retention_days=${this.logSettings.db_log_retention_days}&confirm=true`
|
|
);
|
|
this.successMessage = data.message || 'Old logs cleaned up successfully';
|
|
|
|
// Auto-hide success message after 5 seconds
|
|
setTimeout(() => {
|
|
this.successMessage = null;
|
|
}, 5000);
|
|
|
|
settingsLog.info('Old logs cleaned up successfully');
|
|
} catch (error) {
|
|
settingsLog.error('Failed to cleanup logs:', error);
|
|
this.error = error.response?.data?.detail || 'Failed to cleanup old logs';
|
|
}
|
|
},
|
|
|
|
async saveNotificationSettings() {
|
|
this.saving = true;
|
|
this.error = null;
|
|
this.successMessage = null;
|
|
|
|
try {
|
|
// TODO: Implement API endpoint for notification settings
|
|
// const data = await apiClient.put('/admin/notifications/settings', this.notificationSettings);
|
|
|
|
// For now, just show success (settings are client-side only)
|
|
this.successMessage = 'Notification settings saved successfully';
|
|
|
|
// Auto-hide success message after 5 seconds
|
|
setTimeout(() => {
|
|
this.successMessage = null;
|
|
}, 5000);
|
|
|
|
settingsLog.info('Notification settings saved:', this.notificationSettings);
|
|
} catch (error) {
|
|
settingsLog.error('Failed to save notification settings:', error);
|
|
this.error = error.response?.data?.detail || 'Failed to save notification settings';
|
|
} finally {
|
|
this.saving = false;
|
|
}
|
|
},
|
|
|
|
async loadShippingSettings() {
|
|
try {
|
|
// Load each carrier setting
|
|
const carriers = ['greco', 'colissimo', 'xpresslogistics'];
|
|
for (const carrier of carriers) {
|
|
try {
|
|
const key = `carrier_${carrier}_label_url`;
|
|
const data = await apiClient.get(`/admin/settings/${key}`);
|
|
if (data && data.value) {
|
|
this.shippingSettings[key] = data.value;
|
|
}
|
|
} catch (error) {
|
|
// Setting doesn't exist yet, use default
|
|
settingsLog.debug(`Setting carrier_${carrier}_label_url not found, using default`);
|
|
}
|
|
}
|
|
settingsLog.info('Shipping settings loaded:', this.shippingSettings);
|
|
} catch (error) {
|
|
settingsLog.error('Failed to load shipping settings:', error);
|
|
// Don't show error for missing settings, just use defaults
|
|
}
|
|
},
|
|
|
|
async saveShippingSettings() {
|
|
this.saving = true;
|
|
this.error = null;
|
|
this.successMessage = null;
|
|
|
|
try {
|
|
// Save each carrier setting using upsert
|
|
const carriers = [
|
|
{ key: 'carrier_greco_label_url', name: 'Greco' },
|
|
{ key: 'carrier_colissimo_label_url', name: 'Colissimo' },
|
|
{ key: 'carrier_xpresslogistics_label_url', name: 'XpressLogistics' }
|
|
];
|
|
|
|
for (const carrier of carriers) {
|
|
await apiClient.post('/admin/settings/upsert', {
|
|
key: carrier.key,
|
|
value: this.shippingSettings[carrier.key] || '',
|
|
category: 'shipping',
|
|
value_type: 'string',
|
|
description: `Label URL prefix for ${carrier.name} carrier`
|
|
});
|
|
}
|
|
|
|
this.successMessage = 'Shipping settings saved successfully';
|
|
|
|
// Auto-hide success message after 5 seconds
|
|
setTimeout(() => {
|
|
this.successMessage = null;
|
|
}, 5000);
|
|
|
|
settingsLog.info('Shipping settings saved:', this.shippingSettings);
|
|
} catch (error) {
|
|
settingsLog.error('Failed to save shipping settings:', error);
|
|
this.error = error.response?.data?.detail || 'Failed to save shipping settings';
|
|
} finally {
|
|
this.saving = false;
|
|
}
|
|
},
|
|
|
|
getShippingLabelUrl(carrier, shipmentNumber) {
|
|
// Helper to generate full label URL
|
|
const prefix = this.shippingSettings[`carrier_${carrier}_label_url`] || '';
|
|
if (!prefix || !shipmentNumber) return null;
|
|
return prefix + shipmentNumber;
|
|
}
|
|
};
|
|
}
|
|
|
|
settingsLog.info('Settings module loaded');
|