feat: add backup jobs dashboard and job deletion functionality

This commit is contained in:
Rizqi 2026-06-22 02:43:44 +07:00
parent 34daaad1d2
commit 04fb84c44a
3 changed files with 52 additions and 1 deletions

View File

@ -1023,6 +1023,39 @@ def run_job_now(jobid):
return redirect(url_for('job_detail', jobid=jobid)) return redirect(url_for('job_detail', jobid=jobid))
@app.route('/job/<jobid>/delete', methods=['POST'])
@login_required
def delete_job(jobid):
info = jobs.get(jobid)
if not info:
abort(404)
# Cancel schedule first if it exists
sched_id = info.get('schedule_id')
if sched_id and scheduler:
try:
scheduler.remove_job(sched_id)
except Exception:
pass
# Remove from jobs dict
with jobs_db_lock:
jobs.pop(jobid, None)
save_jobs_db()
# Remove the job directory containing the log file
import shutil
job_dir = JOBS_DIR / jobid
if job_dir.exists():
try:
shutil.rmtree(job_dir)
except Exception as e:
print(f"ERROR: Failed to delete job directory {job_dir}: {e}", file=sys.stderr)
flash('Job and its schedule deleted successfully.', 'success')
return redirect(url_for('list_jobs'))
# ── Template filter ─────────────────────────────────────────────────────────── # ── Template filter ───────────────────────────────────────────────────────────
@app.template_filter('startswith') @app.template_filter('startswith')
def startswith_filter(value, prefix): def startswith_filter(value, prefix):

View File

@ -150,6 +150,14 @@
Run Now Run Now
</button> </button>
</form> </form>
<form method="post" action="/job/{{ job.id }}/delete"
style="margin: 0;"
onsubmit="return confirm('Are you sure you want to delete this job? This will cancel any active schedule and delete the job logs.')">
<button class="btn btn-danger btn-sm" type="submit">
<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="margin-right: 4px;"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/></svg>
Delete
</button>
</form>
{% endif %} {% endif %}
<a href="/jobs" class="btn btn-ghost btn-sm"> <a href="/jobs" class="btn btn-ghost btn-sm">
<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="margin-right: 6px;"><line x1="19" y1="12" x2="5" y2="12"/><polyline points="12 19 5 12 12 5"/></svg> <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="margin-right: 6px;"><line x1="19" y1="12" x2="5" y2="12"/><polyline points="12 19 5 12 12 5"/></svg>

View File

@ -178,7 +178,17 @@
<form method="post" action="/job/{{ job.id }}/cancel-schedule" <form method="post" action="/job/{{ job.id }}/cancel-schedule"
style="margin: 0;" style="margin: 0;"
onsubmit="return confirm('Cancel this schedule?')"> onsubmit="return confirm('Cancel this schedule?')">
<button class="btn btn-danger btn-sm" type="submit">Cancel Schedule</button> <button class="btn btn-secondary btn-sm" type="submit">Cancel Schedule</button>
</form>
{% endif %}
{% if job.status != 'running' and job.status != 'queued' %}
<form method="post" action="/job/{{ job.id }}/delete"
style="margin: 0;"
onsubmit="return confirm('Are you sure you want to delete this job? This will cancel any active schedule and delete the job logs.')">
<button class="btn btn-danger btn-sm" type="submit">
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 4px;"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/></svg>
Delete
</button>
</form> </form>
{% endif %} {% endif %}
</div> </div>