July 4 - Update with recurring/scheduled inspections
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8">
|
||||
<h2 class="mb-4"><i class="bi bi-calendar2-week"></i> {{ title }}</h2>
|
||||
|
||||
<form method="POST" class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Schedule name</label>
|
||||
<input type="text" name="name" class="form-control" required
|
||||
value="{{ schedule.name if schedule else '' }}"
|
||||
placeholder="e.g. Weekly restroom check — Main Office">
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Template</label>
|
||||
<select name="template_id" class="form-select" required>
|
||||
<option value="">— Choose a template —</option>
|
||||
{% for t in templates %}
|
||||
<option value="{{ t.id }}"
|
||||
{{ 'selected' if schedule and schedule.template_id == t.id }}>{{ t.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Frequency</label>
|
||||
<select name="frequency" class="form-select" required>
|
||||
{% for f in frequencies %}
|
||||
<option value="{{ f }}"
|
||||
{{ 'selected' if (schedule and schedule.frequency == f) or (not schedule and f == 'weekly') }}>
|
||||
{{ f|title }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Facility</label>
|
||||
<select name="facility_id" id="facilitySelect" class="form-select" required>
|
||||
<option value="">— Choose a facility —</option>
|
||||
{% for f in facilities %}
|
||||
<option value="{{ f.id }}"
|
||||
{{ 'selected' if schedule and schedule.facility_id == f.id }}>{{ f.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Area <span class="text-muted small">(optional)</span></label>
|
||||
<select name="area_id" id="areaSelect" class="form-select">
|
||||
<option value="">— Whole facility —</option>
|
||||
{% if schedule and schedule.area %}
|
||||
<option value="{{ schedule.area.id }}" selected>{{ schedule.area.name }}</option>
|
||||
{% endif %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Assign to inspector</label>
|
||||
<select name="inspector_id" class="form-select" required>
|
||||
<option value="">— Choose an inspector —</option>
|
||||
{% for u in inspectors %}
|
||||
<option value="{{ u.id }}"
|
||||
{{ 'selected' if schedule and schedule.inspector_id == u.id }}>
|
||||
{{ u.display_name }} ({{ u.role }})</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{% if schedule %}
|
||||
<div class="form-check form-switch mb-1">
|
||||
<input class="form-check-input" type="checkbox" name="active" id="activeSwitch"
|
||||
{{ 'checked' if schedule.active }}>
|
||||
<label class="form-check-label" for="activeSwitch">Active</label>
|
||||
</div>
|
||||
<p class="text-muted small">
|
||||
Saving recomputes the next run from now. Next run:
|
||||
{{ schedule.next_run_at.strftime('%Y-%m-%d %H:%M') if schedule.next_run_at else '—' }}
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="card-footer d-flex justify-content-between">
|
||||
<a href="{{ url_for('inspection_schedules.index') }}" class="btn btn-outline-secondary">Cancel</a>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="bi bi-check-lg"></i> Save Schedule
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Facility → Area cascade, reusing the existing inspections AJAX endpoint.
|
||||
(function () {
|
||||
var facilitySelect = document.getElementById('facilitySelect');
|
||||
var areaSelect = document.getElementById('areaSelect');
|
||||
if (!facilitySelect || !areaSelect) return;
|
||||
|
||||
var preselectedAreaId = {{ (schedule.area_id if schedule and schedule.area_id else 0) | tojson }};
|
||||
|
||||
function loadAreas(facilityId, keepSelection) {
|
||||
areaSelect.innerHTML = '<option value="">— Whole facility —</option>';
|
||||
if (!facilityId) return;
|
||||
fetch('{{ url_for('inspections.areas_for_facility', facility_id=0) }}'.replace('/0', '/' + facilityId))
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (areas) {
|
||||
areas.forEach(function (a) {
|
||||
var opt = document.createElement('option');
|
||||
opt.value = a.id;
|
||||
opt.textContent = a.name;
|
||||
if (keepSelection && a.id === preselectedAreaId) opt.selected = true;
|
||||
areaSelect.appendChild(opt);
|
||||
});
|
||||
})
|
||||
.catch(function () { /* leave the whole-facility default in place */ });
|
||||
}
|
||||
|
||||
facilitySelect.addEventListener('change', function () {
|
||||
preselectedAreaId = 0;
|
||||
loadAreas(this.value, false);
|
||||
});
|
||||
|
||||
// On edit load, refresh the area list for the saved facility and keep the saved area.
|
||||
if (facilitySelect.value) loadAreas(facilitySelect.value, true);
|
||||
})();
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user