Files
JQC_multi_tenant/app/templates/templates/list.html
T
2026-06-26 09:04:34 -04:00

269 lines
12 KiB
HTML

{% extends "base.html" %}
{% block title %}Inspection Templates{% endblock %}
{% block content %}
<div class="row mb-4">
<div class="col-md-6">
<h2><i class="bi bi-file-earmark-text"></i> Inspection Templates</h2>
</div>
<div class="col-md-6 text-end">
{% if current_user.role in ['admin', 'director'] %}
<a href="{{ url_for('templates.create_template') }}" class="btn btn-primary">
<i class="bi bi-plus-circle"></i> Create Template
</a>
{% endif %}
</div>
</div>
<div class="row">
{% for template in templates %}
<div class="col-md-6 col-lg-4 mb-4">
<div class="card shadow-sm h-100 {% if not template.active %}opacity-75 border-secondary{% endif %}">
<div class="card-body">
<h5 class="card-title d-flex align-items-start gap-2">
<a href="{{ url_for('templates.view_template', template_id=template.id) }}" class="text-decoration-none flex-grow-1">
{{ template.name }}
</a>
{% if template.active %}
<span class="badge bg-success flex-shrink-0">Active</span>
{% else %}
<span class="badge bg-secondary flex-shrink-0">Inactive</span>
{% endif %}
</h5>
<p class="card-text text-muted small">{{ template.description or 'No description' }}</p>
<div class="mt-3">
<span class="badge bg-info">{{ template.frequency|title }}</span>
<small class="text-muted ms-2">
<i class="bi bi-check2-square"></i> {{ template.checklist_items.count() }} items
</small>
</div>
</div>
<div class="card-footer bg-transparent d-flex gap-2 align-items-center flex-wrap">
<a href="{{ url_for('templates.view_template', template_id=template.id) }}"
class="btn btn-sm btn-outline-primary">
<i class="bi bi-eye"></i> View
</a>
{% if current_user.role in ['admin', 'director'] %}
<!-- Rename -->
<button type="button"
class="btn btn-sm btn-outline-secondary"
data-bs-toggle="modal"
data-bs-target="#renameModal"
data-template-id="{{ template.id }}"
data-template-name="{{ template.name }}"
data-template-description="{{ template.description or '' }}"
data-template-frequency="{{ template.frequency or 'daily' }}"
title="Edit template details">
<i class="bi bi-pencil"></i> Edit
</button>
<!-- Duplicate -->
<form method="POST"
action="{{ url_for('templates.duplicate_template', template_id=template.id) }}"
class="d-inline">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<button type="submit" class="btn btn-sm btn-outline-secondary"
title="Duplicate template">
<i class="bi bi-copy"></i> Duplicate
</button>
</form>
<!-- Toggle active/inactive -->
<form method="POST"
action="{{ url_for('templates.toggle_active', template_id=template.id) }}"
class="d-inline">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
{% if template.active %}
<button type="submit" class="btn btn-sm btn-outline-warning"
title="Deactivate template">
<i class="bi bi-pause-circle"></i> Deactivate
</button>
{% else %}
<button type="submit" class="btn btn-sm btn-outline-success"
title="Activate template">
<i class="bi bi-play-circle"></i> Activate
</button>
{% endif %}
</form>
<!-- Delete -->
<button type="button"
class="btn btn-sm btn-outline-danger ms-auto"
data-bs-toggle="modal"
data-bs-target="#deleteModal"
data-template-id="{{ template.id }}"
data-template-name="{{ template.name }}"
data-inspection-count="{{ template.inspections.count() }}"
title="Delete template">
<i class="bi bi-trash"></i> Delete
</button>
{% endif %}
</div>
</div>
</div>
{% else %}
<div class="col-12">
<div class="alert alert-info">
<i class="bi bi-info-circle"></i> No templates created yet.
</div>
</div>
{% endfor %}
</div>
{% if current_user.role in ['admin', 'director'] %}
<!-- Edit Template Modal -->
<div class="modal fade" id="renameModal" tabindex="-1" aria-labelledby="renameModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header bg-primary text-white">
<h5 class="modal-title" id="renameModalLabel">
<i class="bi bi-pencil"></i> Edit Template
</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
</div>
<form id="renameTemplateForm" method="POST" action="">
<div class="modal-body">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<div class="mb-3">
<label for="renameInput" class="form-label fw-semibold">Name <span class="text-danger">*</span></label>
<input type="text" id="renameInput" name="name"
class="form-control" maxlength="255"
placeholder="Enter template name" required>
</div>
<div class="mb-3">
<label for="editDescription" class="form-label fw-semibold">Description</label>
<textarea id="editDescription" name="description"
class="form-control" rows="3"
placeholder="Optional description"></textarea>
</div>
<div class="mb-1">
<label for="editFrequency" class="form-label fw-semibold">Frequency</label>
<select id="editFrequency" name="frequency" class="form-select">
<option value="daily">Daily</option>
<option value="weekly">Weekly</option>
<option value="monthly">Monthly</option>
<option value="quarterly">Quarterly</option>
</select>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
<i class="bi bi-x-circle"></i> Cancel
</button>
<button type="submit" class="btn btn-primary">
<i class="bi bi-check-lg"></i> Save Changes
</button>
</div>
</form>
</div>
</div>
</div>
<!-- Delete Confirmation Modal -->
<div class="modal fade" id="deleteModal" tabindex="-1" aria-labelledby="deleteModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header bg-danger text-white">
<h5 class="modal-title" id="deleteModalLabel">
<i class="bi bi-exclamation-triangle-fill"></i> Confirm Deletion
</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p class="mb-1">You are about to permanently delete:</p>
<p class="fw-bold fs-5 mb-3" id="modalTemplateName"></p>
<!-- Shown when template has inspections -->
<div id="modalWarningBlock" class="alert alert-danger d-none mb-0">
<i class="bi bi-x-circle-fill"></i>
<strong>Cannot delete this template.</strong>
It has existing inspection records linked to it.
Remove all associated inspections first.
</div>
<!-- Shown when safe to delete -->
<div id="modalConfirmBlock">
<p class="text-muted mb-0">
This action is <strong>irreversible</strong>.
All checklist items and form schema for this template will be permanently removed.
</p>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
<i class="bi bi-x-circle"></i> Cancel
</button>
<form id="deleteTemplateForm" method="POST" action="" class="d-inline">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<button type="submit" id="confirmDeleteBtn" class="btn btn-danger">
<i class="bi bi-trash-fill"></i> Delete Permanently
</button>
</form>
</div>
</div>
</div>
</div>
{% endif %}
{% endblock %}
{% block extra_js %}
{% if current_user.role in ['admin', 'director'] %}
<script>
document.addEventListener('DOMContentLoaded', function () {
// Edit template modal
const renameModal = document.getElementById('renameModal');
renameModal.addEventListener('show.bs.modal', function (event) {
const btn = event.relatedTarget;
const templateId = btn.getAttribute('data-template-id');
const templateName = btn.getAttribute('data-template-name');
const templateDesc = btn.getAttribute('data-template-description');
const templateFreq = btn.getAttribute('data-template-frequency');
document.getElementById('renameInput').value = templateName;
document.getElementById('editDescription').value = templateDesc;
document.getElementById('editFrequency').value = templateFreq;
document.getElementById('renameTemplateForm').action =
'/templates/' + templateId + '/rename';
renameModal.addEventListener('shown.bs.modal', function focusInput() {
const input = document.getElementById('renameInput');
input.select();
renameModal.removeEventListener('shown.bs.modal', focusInput);
});
});
const deleteModal = document.getElementById('deleteModal');
deleteModal.addEventListener('show.bs.modal', function (event) {
const btn = event.relatedTarget;
const templateId = btn.getAttribute('data-template-id');
const templateName = btn.getAttribute('data-template-name');
const inspectionCount = parseInt(btn.getAttribute('data-inspection-count'), 10);
document.getElementById('modalTemplateName').textContent = templateName;
document.getElementById('deleteTemplateForm').action =
'/templates/' + templateId + '/delete';
const warningBlock = document.getElementById('modalWarningBlock');
const confirmBlock = document.getElementById('modalConfirmBlock');
const confirmBtn = document.getElementById('confirmDeleteBtn');
if (inspectionCount > 0) {
warningBlock.classList.remove('d-none');
confirmBlock.classList.add('d-none');
confirmBtn.disabled = true;
} else {
warningBlock.classList.add('d-none');
confirmBlock.classList.remove('d-none');
confirmBtn.disabled = false;
}
});
});
</script>
{% endif %}
{% endblock %}