feat: add UI templates for creating, detailing, and batch processing backup jobs with associated GUI routing

This commit is contained in:
Rizqi 2026-06-22 02:13:08 +07:00
parent 2598369051
commit 32e86928c4
4 changed files with 145 additions and 12 deletions

View File

@ -109,8 +109,11 @@ def reschedule_active_jobs():
)
elif schedule_type == 'monthly':
hour, minute = (schedule_time.split(':') + ['00'])[:2]
day_val = monthly_day
if str(day_val).isdigit():
day_val = max(1, min(28, int(day_val)))
trigger = CronTrigger(
day=max(1, min(28, int(monthly_day or 1))),
day=day_val,
hour=int(hour), minute=int(minute)
)
elif schedule_type == 'interval':
@ -307,6 +310,8 @@ def job_to_display(jid, info):
'disks_count': len(disk_filter) if disk_filter is not None else None,
'retention_type': info.get('retention_type', 'keep_all'),
'retention_value': info.get('retention_value', 5),
'monthly_day': info.get('monthly_day'),
'weekly_day': info.get('weekly_day'),
}
@ -490,8 +495,11 @@ def create_and_start_job(
)
elif schedule_type == 'monthly':
hour, minute = (schedule_time.split(':') + ['00'])[:2]
day_val = monthly_day
if str(day_val).isdigit():
day_val = max(1, min(28, int(day_val)))
trigger = CronTrigger(
day=max(1, min(28, int(monthly_day or 1))),
day=day_val,
hour=int(hour), minute=int(minute)
)
elif schedule_type == 'interval':
@ -629,8 +637,17 @@ def create_job():
daily_time = request.form.get('daily_time', '02:00')
weekly_day = request.form.get('weekly_day', '0')
weekly_time = request.form.get('weekly_time', '02:00')
monthly_day = request.form.get('monthly_day', '1')
monthly_time = request.form.get('monthly_time', '02:00')
monthly_basis = request.form.get('monthly_basis', 'day_num')
if monthly_basis == 'weekday':
monthly_week_num = request.form.get('monthly_week_num', '1st')
monthly_day_of_week = request.form.get('monthly_day_of_week', 'sun')
monthly_day = f"{monthly_week_num} {monthly_day_of_week}"
monthly_time = request.form.get('monthly_time_2', '02:00')
else:
monthly_day = request.form.get('monthly_day', '1')
monthly_time = request.form.get('monthly_time_1', '02:00')
interval_hrs = request.form.get('interval_hours', '24')
label = request.form.get('job_label', '').strip()
@ -726,8 +743,17 @@ def batch_jobs():
daily_time = request.form.get('daily_time', '02:00')
weekly_day = request.form.get('weekly_day', '0')
weekly_time = request.form.get('weekly_time', '02:00')
monthly_day = request.form.get('monthly_day', '1')
monthly_time = request.form.get('monthly_time', '02:00')
monthly_basis = request.form.get('monthly_basis', 'day_num')
if monthly_basis == 'weekday':
monthly_week_num = request.form.get('monthly_week_num', '1st')
monthly_day_of_week = request.form.get('monthly_day_of_week', 'sun')
monthly_day = f"{monthly_week_num} {monthly_day_of_week}"
monthly_time = request.form.get('monthly_time_2', '02:00')
else:
monthly_day = request.form.get('monthly_day', '1')
monthly_time = request.form.get('monthly_time_1', '02:00')
interval_hrs = request.form.get('interval_hours', '24')
label_prefix = request.form.get('job_label', '').strip()

View File

@ -369,15 +369,54 @@
</div>
</div>
<div class="schedule-detail" id="detail-monthly">
<div class="form-row">
<div class="form-row" style="margin-bottom: 12px;">
<div class="form-group" style="margin:0; grid-column: span 2;">
<label class="form-label" for="monthly_basis">Monthly Schedule Type</label>
<select id="monthly_basis" name="monthly_basis" class="form-control" onchange="onMonthlyBasisChange(this.value)">
<option value="day_num">Specific Day of Month (e.g. 1st, 15th)</option>
<option value="weekday">Specific Weekday of Month (e.g. 1st Sunday, Last Saturday)</option>
</select>
</div>
</div>
<div class="form-row" id="monthly_day_num_row">
<div class="form-group" style="margin:0;">
<label class="form-label" for="monthly_day">Day of month (128)</label>
<input id="monthly_day" class="form-control" type="number"
name="monthly_day" min="1" max="28" value="1" />
</div>
<div class="form-group" style="margin:0;">
<label class="form-label" for="monthly_time">Time (24h)</label>
<input id="monthly_time" class="form-control" type="time" name="monthly_time" value="02:00" />
<label class="form-label" for="monthly_time_1">Time (24h)</label>
<input id="monthly_time_1" class="form-control" type="time" name="monthly_time_1" value="02:00" />
</div>
</div>
<div class="form-row" id="monthly_weekday_row" style="display:none;">
<div class="form-group" style="margin:0;">
<label class="form-label" for="monthly_week_num">Which Week</label>
<select id="monthly_week_num" name="monthly_week_num" class="form-control">
<option value="1st">1st (First)</option>
<option value="2nd">2nd (Second)</option>
<option value="3rd">3rd (Third)</option>
<option value="4th">4th (Fourth)</option>
<option value="last">Last</option>
</select>
</div>
<div class="form-group" style="margin:0;">
<label class="form-label" for="monthly_day_of_week">Day of Week</label>
<select id="monthly_day_of_week" name="monthly_day_of_week" class="form-control">
<option value="sun" selected>Sunday (Weekend)</option>
<option value="sat">Saturday (Weekend)</option>
<option value="mon">Monday</option>
<option value="tue">Tuesday</option>
<option value="wed">Wednesday</option>
<option value="thu">Thursday</option>
<option value="fri">Friday</option>
</select>
</div>
<div class="form-group" style="margin:0; grid-column: span 2; margin-top: 12px;">
<label class="form-label" for="monthly_time_2">Time (24h)</label>
<input id="monthly_time_2" class="form-control" type="time" name="monthly_time_2" value="02:00" />
</div>
</div>
</div>
@ -497,6 +536,18 @@
hint.textContent = 'Backups older than N days will be deleted automatically.';
}
}
function onMonthlyBasisChange(val) {
const dayNumRow = document.getElementById('monthly_day_num_row');
const weekdayRow = document.getElementById('monthly_weekday_row');
if (val === 'day_num') {
dayNumRow.style.display = '';
weekdayRow.style.display = 'none';
} else {
dayNumRow.style.display = 'none';
weekdayRow.style.display = '';
}
}
</script>
{% endblock %}

View File

@ -373,15 +373,54 @@
<!-- Monthly detail -->
<div class="schedule-detail" id="detail-monthly">
<div class="form-row">
<div class="form-row" style="margin-bottom: 12px;">
<div class="form-group" style="margin:0; grid-column: span 2;">
<label class="form-label" for="monthly_basis">Monthly Schedule Type</label>
<select id="monthly_basis" name="monthly_basis" class="form-control" onchange="onMonthlyBasisChange(this.value)">
<option value="day_num">Specific Day of Month (e.g. 1st, 15th)</option>
<option value="weekday">Specific Weekday of Month (e.g. 1st Sunday, Last Saturday)</option>
</select>
</div>
</div>
<div class="form-row" id="monthly_day_num_row">
<div class="form-group" style="margin:0;">
<label class="form-label" for="monthly_day">Day of month (128)</label>
<input id="monthly_day" class="form-control" type="number"
name="monthly_day" min="1" max="28" value="1" />
</div>
<div class="form-group" style="margin:0;">
<label class="form-label" for="monthly_time">Time (24h)</label>
<input id="monthly_time" class="form-control" type="time" name="monthly_time" value="02:00" />
<label class="form-label" for="monthly_time_1">Time (24h)</label>
<input id="monthly_time_1" class="form-control" type="time" name="monthly_time_1" value="02:00" />
</div>
</div>
<div class="form-row" id="monthly_weekday_row" style="display:none;">
<div class="form-group" style="margin:0;">
<label class="form-label" for="monthly_week_num">Which Week</label>
<select id="monthly_week_num" name="monthly_week_num" class="form-control">
<option value="1st">1st (First)</option>
<option value="2nd">2nd (Second)</option>
<option value="3rd">3rd (Third)</option>
<option value="4th">4th (Fourth)</option>
<option value="last">Last</option>
</select>
</div>
<div class="form-group" style="margin:0;">
<label class="form-label" for="monthly_day_of_week">Day of Week</label>
<select id="monthly_day_of_week" name="monthly_day_of_week" class="form-control">
<option value="sun" selected>Sunday (Weekend)</option>
<option value="sat">Saturday (Weekend)</option>
<option value="mon">Monday</option>
<option value="tue">Tuesday</option>
<option value="wed">Wednesday</option>
<option value="thu">Thursday</option>
<option value="fri">Friday</option>
</select>
</div>
<div class="form-group" style="margin:0; grid-column: span 2; margin-top: 12px;">
<label class="form-label" for="monthly_time_2">Time (24h)</label>
<input id="monthly_time_2" class="form-control" type="time" name="monthly_time_2" value="02:00" />
</div>
</div>
</div>
@ -578,5 +617,17 @@
hint.textContent = 'Backups older than N days will be deleted automatically.';
}
}
function onMonthlyBasisChange(val) {
const dayNumRow = document.getElementById('monthly_day_num_row');
const weekdayRow = document.getElementById('monthly_weekday_row');
if (val === 'day_num') {
dayNumRow.style.display = '';
weekdayRow.style.display = 'none';
} else {
dayNumRow.style.display = 'none';
weekdayRow.style.display = '';
}
}
</script>
{% endblock %}

View File

@ -167,6 +167,11 @@
{% if job.schedule_type and job.schedule_type != 'now' %}
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" style="vertical-align: middle; margin-right: 6px;"><path d="M23 4v6h-6"/><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"/></svg>
{{ job.schedule_type|capitalize }}
{% if job.schedule_type == 'monthly' and job.monthly_day is not none %}
(Day: {{ job.monthly_day }})
{% elif job.schedule_type == 'weekly' and job.weekly_day is not none %}
(Day: {{ ['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'][job.weekly_day|int] if (job.weekly_day|string).isdigit() else job.weekly_day }})
{% endif %}
{% if job.schedule_time %}at {{ job.schedule_time }}{% endif %}
{% else %}
One-time (Run Now)