fix: config modal scrollbar, scheduler-config.js, logging API endpoint, static cache-busting

This commit is contained in:
2026-02-22 10:01:52 +01:00
parent 0265ae2a70
commit eed75ff08b
14 changed files with 614 additions and 62 deletions

View File

@@ -35,13 +35,17 @@
max-width: 500px;
width: 90%;
max-height: 80vh;
overflow: hidden;
/* overflow:hidden removed — it was clipping the modal-body scrollbar.
Border-radius clips backgrounds correctly without it on modern browsers. */
display: flex;
flex-direction: column;
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
flex-shrink: 0;
padding: var(--spacing-lg);
border-bottom: 1px solid var(--color-border);
}
@@ -55,6 +59,8 @@
.modal-body {
padding: var(--spacing-lg);
overflow-y: auto;
flex: 1;
min-height: 0;
}
/* Config Section within modals */

View File

@@ -24,21 +24,37 @@ AniWorld.SchedulerConfig = (function() {
if (data.success) {
const config = data.config;
const runtimeStatus = data.status || {};
// Update UI elements
document.getElementById('scheduled-rescan-enabled').checked = config.enabled;
document.getElementById('scheduled-rescan-time').value = config.time || '03:00';
document.getElementById('auto-download-after-rescan').checked = config.auto_download_after_rescan;
document.getElementById('scheduled-rescan-time').value = config.schedule_time || '03:00';
// Update status display
document.getElementById('next-rescan-time').textContent =
config.next_run ? new Date(config.next_run).toLocaleString() : 'Not scheduled';
document.getElementById('last-rescan-time').textContent =
config.last_run ? new Date(config.last_run).toLocaleString() : 'Never';
const autoDownload = document.getElementById('auto-download-after-rescan');
if (autoDownload) {
autoDownload.checked = config.auto_download_after_rescan || false;
}
// Update schedule day checkboxes
const days = config.schedule_days || ['mon','tue','wed','thu','fri','sat','sun'];
['mon','tue','wed','thu','fri','sat','sun'].forEach(function(day) {
const cb = document.getElementById('scheduler-day-' + day);
if (cb) cb.checked = days.indexOf(day) !== -1;
});
// Update status display (runtime fields come from data.status)
const nextRunEl = document.getElementById('scheduler-next-run');
if (nextRunEl) {
nextRunEl.textContent = runtimeStatus.next_run
? new Date(runtimeStatus.next_run).toLocaleString()
: 'Not scheduled';
}
const statusBadge = document.getElementById('scheduler-running-status');
statusBadge.textContent = config.is_running ? 'Running' : 'Stopped';
statusBadge.className = 'info-value status-badge ' + (config.is_running ? 'running' : 'stopped');
if (statusBadge) {
statusBadge.textContent = runtimeStatus.is_running ? 'Running' : 'Stopped';
statusBadge.className = 'info-value status-badge ' + (runtimeStatus.is_running ? 'running' : 'stopped');
}
// Enable/disable time input based on checkbox
toggleTimeInput();
@@ -55,25 +71,45 @@ AniWorld.SchedulerConfig = (function() {
async function save() {
try {
const enabled = document.getElementById('scheduled-rescan-enabled').checked;
const interval = parseInt(document.getElementById('scheduled-rescan-interval').value) || 60;
const scheduleTime = document.getElementById('scheduled-rescan-time').value || '03:00';
// Get current config
const configResponse = await AniWorld.ApiClient.get(AniWorld.Constants.API.CONFIG);
if (!configResponse) return;
const config = await configResponse.json();
// Collect checked day checkboxes
const scheduleDays = ['mon','tue','wed','thu','fri','sat','sun'].filter(function(day) {
const cb = document.getElementById('scheduler-day-' + day);
return cb && cb.checked;
});
// Update scheduler settings
config.scheduler = {
const autoDownloadEl = document.getElementById('auto-download-after-rescan');
const autoDownload = autoDownloadEl ? autoDownloadEl.checked : false;
const intervalEl = document.getElementById('scheduled-rescan-interval');
const interval = intervalEl ? (parseInt(intervalEl.value) || 60) : 60;
// POST directly to the scheduler config endpoint
const payload = {
enabled: enabled,
schedule_time: scheduleTime,
schedule_days: scheduleDays,
auto_download_after_rescan: autoDownload,
interval_minutes: interval
};
// Save updated config
const response = await AniWorld.ApiClient.put(AniWorld.Constants.API.CONFIG, config);
const response = await AniWorld.ApiClient.post(API.SCHEDULER_CONFIG, payload);
if (!response) return;
AniWorld.UI.showToast('Scheduler configuration saved successfully', 'success');
await load();
const result = await response.json();
if (result.success) {
AniWorld.UI.showToast('Scheduler configuration saved successfully', 'success');
// Update next run display from response
const nextRunEl = document.getElementById('scheduler-next-run');
if (nextRunEl && result.status) {
nextRunEl.textContent = result.status.next_run
? new Date(result.status.next_run).toLocaleString()
: 'Not scheduled';
}
} else {
AniWorld.UI.showToast('Failed to save scheduler configuration', 'error');
}
} catch (error) {
console.error('Error saving scheduler config:', error);
AniWorld.UI.showToast('Failed to save scheduler configuration', 'error');

View File

@@ -40,6 +40,7 @@ AniWorld.Constants = (function() {
QUEUE_PENDING: '/api/queue/pending',
// Config endpoints
CONFIG: '/api/config',
CONFIG_DIRECTORY: '/api/config/directory',
CONFIG_SECTION: '/api/config/section', // + /{section}
CONFIG_BACKUP: '/api/config/backup',

View File

@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Error - Aniworld</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/css/styles.css" rel="stylesheet">
<link href="/static/css/styles.css?v={{ static_v }}" rel="stylesheet">
</head>
<body>
<div class="container mt-5">

View File

@@ -5,11 +5,11 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AniWorld Manager</title>
<link rel="stylesheet" href="/static/css/styles.css">
<link rel="stylesheet" href="/static/css/styles.css?v={{ static_v }}">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<!-- UX Enhancement and Mobile & Accessibility CSS -->
<link rel="stylesheet" href="/static/css/ux_features.css">
<link rel="stylesheet" href="/static/css/ux_features.css?v={{ static_v }}">
</head>
<body>
@@ -649,32 +649,32 @@
</div>
<!-- Shared Modules (load in dependency order) -->
<script src="/static/js/shared/constants.js"></script>
<script src="/static/js/shared/auth.js"></script>
<script src="/static/js/shared/api-client.js"></script>
<script src="/static/js/shared/theme.js"></script>
<script src="/static/js/shared/ui-utils.js"></script>
<script src="/static/js/shared/websocket-client.js"></script>
<script src="/static/js/shared/constants.js?v={{ static_v }}"></script>
<script src="/static/js/shared/auth.js?v={{ static_v }}"></script>
<script src="/static/js/shared/api-client.js?v={{ static_v }}"></script>
<script src="/static/js/shared/theme.js?v={{ static_v }}"></script>
<script src="/static/js/shared/ui-utils.js?v={{ static_v }}"></script>
<script src="/static/js/shared/websocket-client.js?v={{ static_v }}"></script>
<!-- External modules -->
<script src="/static/js/localization.js"></script>
<script src="/static/js/user_preferences.js"></script>
<script src="/static/js/localization.js?v={{ static_v }}"></script>
<script src="/static/js/user_preferences.js?v={{ static_v }}"></script>
<!-- Index Page Modules -->
<script src="/static/js/index/series-manager.js"></script>
<script src="/static/js/index/selection-manager.js"></script>
<script src="/static/js/index/search.js"></script>
<script src="/static/js/index/scan-manager.js"></script>
<script src="/static/js/index/nfo-manager.js"></script>
<script src="/static/js/index/series-manager.js?v={{ static_v }}"></script>
<script src="/static/js/index/selection-manager.js?v={{ static_v }}"></script>
<script src="/static/js/index/search.js?v={{ static_v }}"></script>
<script src="/static/js/index/scan-manager.js?v={{ static_v }}"></script>
<script src="/static/js/index/nfo-manager.js?v={{ static_v }}"></script>
<!-- Config Sub-Modules (must load before config-manager.js) -->
<script src="/static/js/index/scheduler-config.js"></script>
<script src="/static/js/index/logging-config.js"></script>
<script src="/static/js/index/advanced-config.js"></script>
<script src="/static/js/index/main-config.js"></script>
<script src="/static/js/index/nfo-config.js"></script>
<script src="/static/js/index/config-manager.js"></script>
<script src="/static/js/index/socket-handler.js"></script>
<script src="/static/js/index/app-init.js"></script>
<script src="/static/js/index/scheduler-config.js?v={{ static_v }}"></script>
<script src="/static/js/index/logging-config.js?v={{ static_v }}"></script>
<script src="/static/js/index/advanced-config.js?v={{ static_v }}"></script>
<script src="/static/js/index/main-config.js?v={{ static_v }}"></script>
<script src="/static/js/index/nfo-config.js?v={{ static_v }}"></script>
<script src="/static/js/index/config-manager.js?v={{ static_v }}"></script>
<script src="/static/js/index/socket-handler.js?v={{ static_v }}"></script>
<script src="/static/js/index/app-init.js?v={{ static_v }}"></script>
</body>
</html>

View File

@@ -5,7 +5,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AniWorld Manager - Initializing</title>
<link rel="stylesheet" href="/static/css/styles.css">
<link rel="stylesheet" href="/static/css/styles.css?v={{ static_v }}">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<style>
.loading-container {

View File

@@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AniWorld Manager - Login</title>
<link rel="stylesheet" href="/static/css/styles.css">
<link rel="stylesheet" href="/static/css/styles.css?v={{ static_v }}">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<style>
.login-container {

View File

@@ -5,7 +5,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Download Queue - AniWorld Manager</title>
<link rel="stylesheet" href="/static/css/styles.css">
<link rel="stylesheet" href="/static/css/styles.css?v={{ static_v }}">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
</head>
@@ -234,19 +234,19 @@
</div>
<!-- Shared Modules (load in dependency order) -->
<script src="/static/js/shared/constants.js"></script>
<script src="/static/js/shared/auth.js"></script>
<script src="/static/js/shared/api-client.js"></script>
<script src="/static/js/shared/theme.js"></script>
<script src="/static/js/shared/ui-utils.js"></script>
<script src="/static/js/shared/websocket-client.js"></script>
<script src="/static/js/shared/constants.js?v={{ static_v }}"></script>
<script src="/static/js/shared/auth.js?v={{ static_v }}"></script>
<script src="/static/js/shared/api-client.js?v={{ static_v }}"></script>
<script src="/static/js/shared/theme.js?v={{ static_v }}"></script>
<script src="/static/js/shared/ui-utils.js?v={{ static_v }}"></script>
<script src="/static/js/shared/websocket-client.js?v={{ static_v }}"></script>
<!-- Queue Page Modules -->
<script src="/static/js/queue/queue-api.js"></script>
<script src="/static/js/queue/queue-renderer.js"></script>
<script src="/static/js/queue/progress-handler.js"></script>
<script src="/static/js/queue/queue-socket-handler.js"></script>
<script src="/static/js/queue/queue-init.js"></script>
<script src="/static/js/queue/queue-api.js?v={{ static_v }}"></script>
<script src="/static/js/queue/queue-renderer.js?v={{ static_v }}"></script>
<script src="/static/js/queue/progress-handler.js?v={{ static_v }}"></script>
<script src="/static/js/queue/queue-socket-handler.js?v={{ static_v }}"></script>
<script src="/static/js/queue/queue-init.js?v={{ static_v }}"></script>
</body>
</html>

View File

@@ -5,7 +5,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AniWorld Manager - Setup</title>
<link rel="stylesheet" href="/static/css/styles.css">
<link rel="stylesheet" href="/static/css/styles.css?v={{ static_v }}">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<style>
.setup-container {

View File

@@ -5,7 +5,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AniWorld Manager - Setup</title>
<link rel="stylesheet" href="/static/css/styles.css">
<link rel="stylesheet" href="/static/css/styles.css?v={{ static_v }}">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<style>
.setup-container {