fix: config modal scrollbar, scheduler-config.js, logging API endpoint, static cache-busting
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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>
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user