156 lines
6.6 KiB
HTML
156 lines
6.6 KiB
HTML
{% extends 'base.html' %}
|
||
{% block title %}{{ tpl.name }} – Templates{% endblock %}
|
||
{% block breadcrumb %}
|
||
<li class="breadcrumb-item"><a href="{{ url_for('dashboard.index') }}">Home</a></li>
|
||
<li class="breadcrumb-item"><a href="{{ url_for('doc_templates.index') }}">Templates</a></li>
|
||
<li class="breadcrumb-item active">{{ tpl.name }}</li>
|
||
{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="page-header d-flex align-items-center justify-content-between mb-4">
|
||
<h1><i class="bi bi-file-earmark-word me-2"></i>{{ tpl.name }}</h1>
|
||
<div class="d-flex gap-2">
|
||
<a href="{{ url_for('doc_templates.download', tpl_id=tpl.id) }}" class="btn btn-sm btn-outline-secondary">
|
||
<i class="bi bi-download me-1"></i>Download .docx
|
||
</a>
|
||
<a href="{{ url_for('doc_templates.edit', tpl_id=tpl.id) }}" class="btn btn-sm btn-outline-primary">
|
||
<i class="bi bi-pencil me-1"></i>Edit details
|
||
</a>
|
||
<form method="POST" action="{{ url_for('doc_templates.rescan', tpl_id=tpl.id) }}" class="d-inline">
|
||
<button type="submit" class="btn btn-sm btn-outline-secondary">
|
||
<i class="bi bi-arrow-clockwise me-1"></i>Re-scan variables
|
||
</button>
|
||
</form>
|
||
<button class="btn btn-sm btn-outline-danger" data-bs-toggle="modal" data-bs-target="#deleteModal">
|
||
<i class="bi bi-trash me-1"></i>Delete
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="row g-4">
|
||
<!-- Metadata -->
|
||
<div class="col-md-4">
|
||
<div class="card border-0 shadow-sm h-100">
|
||
<div class="card-header bg-white fw-semibold small text-uppercase text-muted">Details</div>
|
||
<div class="card-body">
|
||
<dl class="row small mb-0">
|
||
<dt class="col-5">Category</dt>
|
||
<dd class="col-7">
|
||
{% if tpl.category %}
|
||
<span class="badge bg-secondary">{{ dict(doc_types)[tpl.category] if tpl.category in dict(doc_types) else tpl.category }}</span>
|
||
{% else %}<span class="text-muted">—</span>{% endif %}
|
||
</dd>
|
||
<dt class="col-5">File</dt>
|
||
<dd class="col-7"><code>{{ tpl.filename }}</code></dd>
|
||
<dt class="col-5">Uploaded</dt>
|
||
<dd class="col-7">{{ tpl.created_at.strftime('%d %b %Y %H:%M') }}</dd>
|
||
<dt class="col-5">By</dt>
|
||
<dd class="col-7">{{ tpl.created_by.username if tpl.created_by else '—' }}</dd>
|
||
<dt class="col-5">Docs generated</dt>
|
||
<dd class="col-7">{{ tpl.paperwork_docs.count() }}</dd>
|
||
</dl>
|
||
{% if tpl.description %}
|
||
<hr class="my-2">
|
||
<p class="small text-muted mb-0">{{ tpl.description }}</p>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Variables -->
|
||
<div class="col-md-8">
|
||
<div class="card border-0 shadow-sm">
|
||
<div class="card-header bg-white fw-semibold small text-uppercase text-muted d-flex justify-content-between align-items-center">
|
||
Detected Variables
|
||
<span class="badge bg-primary rounded-pill">{{ tpl.variables | length }}</span>
|
||
</div>
|
||
{% set vars = tpl.variables %}
|
||
{% if vars %}
|
||
<div class="card-body">
|
||
<p class="small text-muted mb-3">
|
||
These placeholders were detected in the template file.
|
||
They will be filled automatically when generating a document.
|
||
<strong class="text-danger">PII variables</strong> (name, email, phone)
|
||
are replaced with <code>[MASKED]</code> when a user's record is erased.
|
||
</p>
|
||
{% set pii = ['user_name','user_email','user_phone'] %}
|
||
<div class="row row-cols-2 row-cols-md-3 g-2">
|
||
{% for v in vars %}
|
||
<div class="col">
|
||
<span class="badge {% if v in pii %}bg-danger{% else %}bg-light text-dark border{% endif %} w-100 text-start p-2">
|
||
{% if v in pii %}<i class="bi bi-shield-x me-1"></i>{% else %}<i class="bi bi-braces me-1"></i>{% endif %}
|
||
{{ v }}
|
||
</span>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
<div class="mt-3 small">
|
||
<span class="badge bg-danger me-1">PII</span> masked on departure
|
||
<span class="badge bg-light text-dark border me-1">other</span> retained
|
||
</div>
|
||
</div>
|
||
{% else %}
|
||
<div class="card-body text-muted small">
|
||
No variables detected. Make sure your template uses <code>{{ variable_name }}</code> syntax
|
||
and click <strong>Re-scan</strong>.
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Documents generated from this template -->
|
||
{% set recent_docs = tpl.paperwork_docs.order_by('created_at desc').limit(10).all() %}
|
||
{% if recent_docs %}
|
||
<div class="card border-0 shadow-sm mt-4">
|
||
<div class="card-header bg-white fw-semibold small text-uppercase text-muted">Recently Generated Documents</div>
|
||
<div class="table-responsive">
|
||
<table class="table table-sm table-hover mb-0 small">
|
||
<thead class="table-light">
|
||
<tr><th>Title</th><th>User</th><th>Created</th><th>Signed</th><th></th></tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for doc in recent_docs %}
|
||
<tr>
|
||
<td>{{ doc.title }}</td>
|
||
<td>{{ doc.user.display_name if doc.user else '—' }}</td>
|
||
<td>{{ doc.created_at.strftime('%d/%m/%Y') }}</td>
|
||
<td>{% if doc.is_signed %}<i class="bi bi-check-circle text-success"></i>{% else %}<span class="text-muted">—</span>{% endif %}</td>
|
||
<td><a href="{{ url_for('paperwork.detail', doc_id=doc.id) }}" class="btn btn-sm btn-outline-secondary py-0 px-2"><i class="bi bi-eye"></i></a></td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
|
||
<!-- Delete modal -->
|
||
<div class="modal fade" id="deleteModal" tabindex="-1">
|
||
<div class="modal-dialog">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title">Delete Template</h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||
</div>
|
||
<div class="modal-body">
|
||
Delete <strong>{{ tpl.name }}</strong>?
|
||
{% if tpl.paperwork_docs.count() > 0 %}
|
||
<div class="alert alert-danger mt-2 small">
|
||
Cannot delete — {{ tpl.paperwork_docs.count() }} document(s) were generated from this template.
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button class="btn btn-secondary btn-sm" data-bs-dismiss="modal">Cancel</button>
|
||
{% if tpl.paperwork_docs.count() == 0 %}
|
||
<form method="POST" action="{{ url_for('doc_templates.delete', tpl_id=tpl.id) }}">
|
||
<button class="btn btn-danger btn-sm" type="submit">Delete</button>
|
||
</form>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endblock %}
|