Add sent emails log to /emails page with full body preview modal
This commit is contained in:
parent
639f093175
commit
d31af062ed
2 changed files with 100 additions and 11 deletions
12
app.py
12
app.py
|
|
@ -3510,10 +3510,20 @@ def emails():
|
|||
email_config_valid = bool(EMAIL_CONFIG['email_address'] and EMAIL_CONFIG['email_password'])
|
||||
emails_list = get_emails() if email_config_valid else []
|
||||
|
||||
# Gesendete Emails aus DB laden
|
||||
con = sqlite3.connect(EMAIL_JOURNAL_DB)
|
||||
con.row_factory = sqlite3.Row
|
||||
sent_emails_list = con.execute(
|
||||
"SELECT * FROM sent_emails ORDER BY sent_at DESC LIMIT 200"
|
||||
).fetchall()
|
||||
sent_emails_list = [dict(r) for r in sent_emails_list]
|
||||
con.close()
|
||||
|
||||
return render_template('emails.html',
|
||||
emails=emails_list,
|
||||
email_config_valid=email_config_valid,
|
||||
current_email=EMAIL_CONFIG['email_address'])
|
||||
current_email=EMAIL_CONFIG['email_address'],
|
||||
sent_emails=sent_emails_list)
|
||||
|
||||
|
||||
@app.route('/emails/<email_id>')
|
||||
|
|
|
|||
|
|
@ -110,17 +110,87 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-4 mt-4">
|
||||
<!-- Gesendete Emails Log -->
|
||||
<div class="row g-4 mt-2">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header bg-secondary d-flex justify-content-between align-items-center">
|
||||
<h5 class="mb-0">📋 Email Journal / Log</h5>
|
||||
<a href="/email-log" class="btn btn-sm btn-outline-light">Vollständiges Log</a>
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="mb-0">Gesendete Emails</h5>
|
||||
<span class="badge bg-secondary">{{ sent_emails|length }} Einträge</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="text-muted">
|
||||
Das vollständige Email-Journal zeigt alle verarbeiteten Emails mit Details zu Status, Agent-Zuweisungen und Zeitstempeln.
|
||||
</p>
|
||||
<div class="card-body p-0">
|
||||
{% if sent_emails %}
|
||||
<div class="table-responsive" style="max-height:600px;overflow-y:auto;">
|
||||
<table class="table table-hover mb-0" style="font-size:.83rem;">
|
||||
<thead style="position:sticky;top:0;z-index:1;background:var(--bg-elevated);">
|
||||
<tr>
|
||||
<th style="width:40px;">#</th>
|
||||
<th style="width:170px;">Zeitpunkt</th>
|
||||
<th>An</th>
|
||||
<th>Betreff</th>
|
||||
<th style="width:160px;">Von Agent</th>
|
||||
<th style="width:70px;">Task</th>
|
||||
<th style="width:60px;">Status</th>
|
||||
<th style="width:50px;"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for mail in sent_emails %}
|
||||
<tr>
|
||||
<td style="color:var(--text-muted);">{{ mail.id }}</td>
|
||||
<td style="color:var(--text-muted);white-space:nowrap;">{{ mail.sent_at[:16].replace('T',' ') }}</td>
|
||||
<td style="font-weight:500;">{{ mail.to_address }}</td>
|
||||
<td>{{ mail.subject }}</td>
|
||||
<td style="color:var(--text-muted);">{{ mail.triggered_by }}</td>
|
||||
<td style="color:var(--text-muted);">{% if mail.task_id %}#{{ mail.task_id }}{% endif %}</td>
|
||||
<td>
|
||||
{% if mail.status == 'sent' %}
|
||||
<span class="badge bg-success">gesendet</span>
|
||||
{% elif mail.status == 'error' %}
|
||||
<span class="badge bg-danger">Fehler</span>
|
||||
{% else %}
|
||||
<span class="badge bg-secondary">{{ mail.status }}</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<button class="btn btn-sm btn-outline-secondary"
|
||||
onclick="showSentEmail({{ mail.id }}, {{ mail.to_address|tojson }}, {{ mail.subject|tojson }}, {{ mail.sent_at|tojson }}, {{ mail.triggered_by|tojson }}, {{ (mail.body or '')|tojson }})"
|
||||
title="Inhalt anzeigen">
|
||||
🔍
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="text-center py-5" style="color:var(--text-muted);">Noch keine Emails gesendet.</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sent Email Detail Modal -->
|
||||
<div class="modal fade" id="sentEmailModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-lg modal-dialog-scrollable">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<div>
|
||||
<h5 class="modal-title mb-1" id="sentEmailSubject"></h5>
|
||||
<div style="font-size:.8rem;color:var(--text-muted);">
|
||||
An: <span id="sentEmailTo"></span> ·
|
||||
<span id="sentEmailDate"></span> ·
|
||||
Von: <span id="sentEmailAgent"></span>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body p-0">
|
||||
<pre id="sentEmailBody" style="background:var(--bg-elevated);color:var(--text-primary);
|
||||
border-radius:0;padding:1.25rem;white-space:pre-wrap;margin:0;
|
||||
font-size:.84rem;line-height:1.6;max-height:70vh;overflow-y:auto;"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -140,5 +210,14 @@ function viewEmail(emailId, subject, from) {
|
|||
.then(d => { document.getElementById('emailBody').textContent = d.content; })
|
||||
.catch(e => { document.getElementById('emailBody').textContent = 'Fehler: ' + e.message; });
|
||||
}
|
||||
|
||||
function showSentEmail(id, to, subject, date, agent, body) {
|
||||
document.getElementById('sentEmailSubject').textContent = subject;
|
||||
document.getElementById('sentEmailTo').textContent = to;
|
||||
document.getElementById('sentEmailDate').textContent = date.replace('T', ' ').slice(0, 16);
|
||||
document.getElementById('sentEmailAgent').textContent = agent;
|
||||
document.getElementById('sentEmailBody').textContent = body || '(kein Inhalt gespeichert)';
|
||||
new bootstrap.Modal(document.getElementById('sentEmailModal')).show();
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue