Add sent emails log to /emails page with full body preview modal

This commit is contained in:
eric 2026-02-23 08:43:13 +00:00
parent 639f093175
commit d31af062ed
2 changed files with 100 additions and 11 deletions

16
app.py
View file

@ -3509,11 +3509,21 @@ def emails():
email_config_valid = bool(EMAIL_CONFIG['email_address'] and EMAIL_CONFIG['email_password']) email_config_valid = bool(EMAIL_CONFIG['email_address'] and EMAIL_CONFIG['email_password'])
emails_list = get_emails() if email_config_valid else [] emails_list = get_emails() if email_config_valid else []
return render_template('emails.html', # 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, emails=emails_list,
email_config_valid=email_config_valid, 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>') @app.route('/emails/<email_id>')

View file

@ -110,17 +110,87 @@
</div> </div>
</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="col-12">
<div class="card"> <div class="card">
<div class="card-header bg-secondary d-flex justify-content-between align-items-center"> <div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0">📋 Email Journal / Log</h5> <h5 class="mb-0">Gesendete Emails</h5>
<a href="/email-log" class="btn btn-sm btn-outline-light">Vollständiges Log</a> <span class="badge bg-secondary">{{ sent_emails|length }} Einträge</span>
</div> </div>
<div class="card-body"> <div class="card-body p-0">
<p class="text-muted"> {% if sent_emails %}
Das vollständige Email-Journal zeigt alle verarbeiteten Emails mit Details zu Status, Agent-Zuweisungen und Zeitstempeln. <div class="table-responsive" style="max-height:600px;overflow-y:auto;">
</p> <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">
&#128269;
</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> &nbsp;·&nbsp;
<span id="sentEmailDate"></span> &nbsp;·&nbsp;
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> </div>
</div> </div>
@ -140,5 +210,14 @@ function viewEmail(emailId, subject, from) {
.then(d => { document.getElementById('emailBody').textContent = d.content; }) .then(d => { document.getElementById('emailBody').textContent = d.content; })
.catch(e => { document.getElementById('emailBody').textContent = 'Fehler: ' + e.message; }); .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> </script>
{% endblock %} {% endblock %}