better reader for mails

This commit is contained in:
2025-06-02 10:33:26 +02:00
parent 5a9b6be79d
commit fdef0c5f66
5 changed files with 103 additions and 101 deletions

View File

@@ -655,6 +655,16 @@ def init_routes(main_bp):
# Get email templates for the email templates tab # Get email templates for the email templates tab
email_templates = EmailTemplate.query.filter_by(is_active=True).all() email_templates = EmailTemplate.query.filter_by(is_active=True).all()
# Get mails for the mails tab
mails = None
if active_tab == 'mails':
page = request.args.get('page', 1, type=int)
per_page = 10
mails = Mail.query.order_by(Mail.created_at.desc()).paginate(page=page, per_page=per_page)
total_pages = mails.pages
current_page = mails.page
users = User.query.order_by(User.username).all()
if request.method == 'GET': if request.method == 'GET':
company_form.company_name.data = site_settings.company_name company_form.company_name.data = site_settings.company_name
company_form.company_website.data = site_settings.company_website company_form.company_website.data = site_settings.company_website
@@ -674,6 +684,7 @@ def init_routes(main_bp):
active_tab=active_tab, active_tab=active_tab,
site_settings=site_settings, site_settings=site_settings,
events=events.items if events else None, events=events.items if events else None,
mails=mails,
total_pages=total_pages, total_pages=total_pages,
current_page=current_page, current_page=current_page,
users=users, users=users,

View File

@@ -46,7 +46,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for mail in mails %} {% for mail in mails.items %}
<tr> <tr>
<td>{{ mail.created_at.strftime('%Y-%m-%d %H:%M:%S') }}</td> <td>{{ mail.created_at.strftime('%Y-%m-%d %H:%M:%S') }}</td>
<td>{{ mail.recipient }}</td> <td>{{ mail.recipient }}</td>
@@ -88,116 +88,84 @@
<!-- Mail Details Modal --> <!-- Mail Details Modal -->
<div class="modal fade" id="mailDetailsModal" tabindex="-1"> <div class="modal fade" id="mailDetailsModal" tabindex="-1">
<div class="modal-dialog modal-lg"> <div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header" style="background-color: var(--primary-opacity-8);">
<h5 class="modal-title">Mail Details</h5> <h5 class="modal-title">
<i class="fas fa-envelope me-2" style="color: var(--primary-color);"></i>Mail Details
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button> <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="mb-3"> <div class="row g-3">
<label class="fw-bold">Subject:</label> <div class="col-md-6">
<p id="modalSubject"></p> <div class="card h-100 border-0 shadow-sm">
<div class="card-body">
<div class="d-flex align-items-center mb-3">
<i class="fas fa-user-circle me-2" style="color: var(--primary-color);"></i>
<h6 class="card-subtitle mb-0" style="color: var(--primary-color); font-weight: 600;">Recipient Information</h6>
</div>
<div class="mb-3">
<label class="fw-bold" style="color: var(--primary-color);">Recipient:</label>
<p id="modalRecipient" class="mb-0"></p>
</div>
<div class="mb-3">
<label class="fw-bold" style="color: var(--primary-color);">Status:</label>
<p id="modalStatus" class="mb-0"></p>
</div>
<div class="mb-3">
<label class="fw-bold" style="color: var(--primary-color);">Template:</label>
<p id="modalTemplate" class="mb-0"></p>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body">
<div class="d-flex align-items-center mb-3">
<i class="fas fa-clock me-2" style="color: var(--primary-color);"></i>
<h6 class="card-subtitle mb-0" style="color: var(--primary-color); font-weight: 600;">Timing Information</h6>
</div>
<div class="mb-3">
<label class="fw-bold" style="color: var(--primary-color);">Created At:</label>
<p id="modalCreatedAt" class="mb-0"></p>
</div>
<div class="mb-3">
<label class="fw-bold" style="color: var(--primary-color);">Sent At:</label>
<p id="modalSentAt" class="mb-0"></p>
</div>
</div>
</div>
</div>
</div> </div>
<div class="mb-3"> <div class="mt-4">
<label class="fw-bold">Recipient:</label> <div class="card border-0 shadow-sm">
<p id="modalRecipient"></p> <div class="card-body">
</div> <div class="d-flex align-items-center mb-3">
<div class="mb-3"> <i class="fas fa-envelope-open-text me-2" style="color: var(--primary-color);"></i>
<label class="fw-bold">Status:</label> <h6 class="card-subtitle mb-0" style="color: var(--primary-color); font-weight: 600;">Message Content</h6>
<p id="modalStatus"></p> </div>
</div> <div class="mb-3">
<div class="mb-3"> <label class="fw-bold" style="color: var(--primary-color);">Subject:</label>
<label class="fw-bold">Template:</label> <p id="modalSubject" class="mb-3"></p>
<p id="modalTemplate"></p> </div>
</div> <div>
<div class="mb-3"> <label class="fw-bold" style="color: var(--primary-color);">Body:</label>
<label class="fw-bold">Created At:</label> <div id="modalBody" class="border rounded p-3 mt-2" style="max-height: 300px; overflow-y: auto; background-color: var(--primary-opacity-8);"></div>
<p id="modalCreatedAt"></p> </div>
</div> </div>
<div class="mb-3"> </div>
<label class="fw-bold">Sent At:</label>
<p id="modalSentAt"></p>
</div>
<div class="mb-3">
<label class="fw-bold">Body:</label>
<div id="modalBody" class="border p-3 bg-light"></div>
</div> </div>
</div> </div>
<div class="modal-footer" style="background-color: var(--primary-opacity-8);">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div> </div>
</div> </div>
</div> </div>
<script> <script>
function updateFilters() {
const status = document.getElementById('statusFilter').value;
const dateRange = document.getElementById('dateRangeFilter').value;
const userId = document.getElementById('userFilter').value;
fetch(`/settings/mails?status=${status}&date_range=${dateRange}&user_id=${userId}`, {
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(response => response.text())
.then(html => {
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
const newTable = doc.querySelector('.table-responsive');
const newPagination = doc.querySelector('.d-flex.justify-content-between.align-items-center.mt-4');
if (newTable) {
document.querySelector('.table-responsive').innerHTML = newTable.innerHTML;
}
if (newPagination) {
const existingPagination = document.querySelector('.d-flex.justify-content-between.align-items-center.mt-4');
if (existingPagination) {
existingPagination.innerHTML = newPagination.innerHTML;
} else {
document.querySelector('.card-body').appendChild(newPagination);
}
}
});
}
function clearFilters() {
document.getElementById('statusFilter').value = '';
document.getElementById('dateRangeFilter').value = '7d';
document.getElementById('userFilter').value = '';
updateFilters();
}
function changePage(page) {
const status = document.getElementById('statusFilter').value;
const dateRange = document.getElementById('dateRangeFilter').value;
const userId = document.getElementById('userFilter').value;
fetch(`/settings/mails?status=${status}&date_range=${dateRange}&user_id=${userId}&page=${page}`, {
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(response => response.text())
.then(html => {
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
const newTable = doc.querySelector('.table-responsive');
const newPagination = doc.querySelector('.d-flex.justify-content-between.align-items-center.mt-4');
if (newTable) {
document.querySelector('.table-responsive').innerHTML = newTable.innerHTML;
}
if (newPagination) {
const existingPagination = document.querySelector('.d-flex.justify-content-between.align-items-center.mt-4');
if (existingPagination) {
existingPagination.innerHTML = newPagination.innerHTML;
} else {
document.querySelector('.card-body').appendChild(newPagination);
}
}
});
}
function viewMailDetails(mailId) { function viewMailDetails(mailId) {
fetch(`/settings/mails/${mailId}`) fetch(`/settings/mails/${mailId}`)
.then(response => response.json()) .then(response => response.json())
@@ -225,5 +193,25 @@ function downloadMailLog() {
window.location.href = `/settings/mails/download?status=${status}&date_range=${dateRange}&user_id=${userId}`; window.location.href = `/settings/mails/download?status=${status}&date_range=${dateRange}&user_id=${userId}`;
} }
function updateFilters() {
const status = document.getElementById('statusFilter').value;
const dateRange = document.getElementById('dateRangeFilter').value;
const userId = document.getElementById('userFilter').value;
window.location.href = `/settings/mails?status=${status}&date_range=${dateRange}&user_id=${userId}`;
}
function clearFilters() {
window.location.href = '/settings/mails';
}
function changePage(page) {
const status = document.getElementById('statusFilter').value;
const dateRange = document.getElementById('dateRangeFilter').value;
const userId = document.getElementById('userFilter').value;
window.location.href = `/settings/mails?page=${page}&status=${status}&date_range=${dateRange}&user_id=${userId}`;
}
</script> </script>
{% endmacro %} {% endmacro %}

View File

@@ -20,10 +20,13 @@ def generate_mail_from_notification(notif: Notif) -> Optional[Mail]:
""" """
logger.debug(f"Generating mail for notification: {notif}") logger.debug(f"Generating mail for notification: {notif}")
# Convert notification type to template name format (e.g., 'account_created' -> 'Account Created')
template_name = ' '.join(word.capitalize() for word in notif.notif_type.split('_'))
# Find the corresponding email template based on notif_type # Find the corresponding email template based on notif_type
template = EmailTemplate.query.filter_by(name=notif.notif_type).first() template = EmailTemplate.query.filter_by(name=template_name).first()
if not template: if not template:
logger.warning(f"No email template found for notification type: {notif.notif_type}") logger.warning(f"No email template found for notification type: {notif.notif_type} (template name: {template_name})")
return None return None
try: try: