2026-08-14 18:02:25 +02:00
|
|
|
{% extends "base.html" %}
|
|
|
|
|
|
|
|
|
|
{% block title %}{{ mail.subject|truncate(50, true) }} - Outlook{% endblock %}
|
|
|
|
|
|
|
|
|
|
{% block content %}
|
|
|
|
|
<div class="container-fluid">
|
|
|
|
|
<div class="row mb-4">
|
|
|
|
|
<div class="col">
|
|
|
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
|
|
|
<div>
|
|
|
|
|
<h1>📧 Email</h1>
|
|
|
|
|
<nav aria-label="breadcrumb">
|
|
|
|
|
<ol class="breadcrumb">
|
|
|
|
|
<li class="breadcrumb-item"><a href="{{ url_for('outlook_dashboard.dashboard') }}">Outlook</a></li>
|
|
|
|
|
<li class="breadcrumb-item"><a href="{{ url_for('outlook_pages.account_detail', account_id=mail.account_id) }}">Mails</a></li>
|
|
|
|
|
<li class="breadcrumb-item active">{{ mail.subject|truncate(30, true) }}</li>
|
|
|
|
|
</ol>
|
|
|
|
|
</nav>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<a href="{{ url_for('outlook_pages.account_detail', account_id=mail.account_id) }}" class="btn btn-outline-secondary">
|
|
|
|
|
<i class="fas fa-arrow-left"></i> Retour à la liste
|
|
|
|
|
</a>
|
|
|
|
|
<div class="btn-group">
|
|
|
|
|
{% if not mail.is_read %}
|
|
|
|
|
<button onclick="markAsRead({{ mail.id }})" class="btn btn-outline-success">
|
|
|
|
|
<i class="fas fa-check"></i> Marquer comme lu
|
|
|
|
|
</button>
|
|
|
|
|
{% endif %}
|
|
|
|
|
<button onclick="deleteMail({{ mail.id }})" class="btn btn-outline-danger">
|
|
|
|
|
<i class="fas fa-trash"></i> Supprimer
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- Détails du mail -->
|
|
|
|
|
<div class="row">
|
|
|
|
|
<div class="col-12">
|
|
|
|
|
<div class="card">
|
|
|
|
|
<div class="card-header">
|
|
|
|
|
<div class="row align-items-center">
|
|
|
|
|
<div class="col">
|
|
|
|
|
<h5 class="mb-0">{{ mail.subject }}</h5>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-auto">
|
|
|
|
|
{% if mail.importance == 'high' %}
|
|
|
|
|
<span class="badge bg-danger">Urgent</span>
|
|
|
|
|
{% elif mail.importance == 'low' %}
|
|
|
|
|
<span class="badge bg-secondary">Faible priorité</span>
|
|
|
|
|
{% endif %}
|
|
|
|
|
{% if mail.is_read %}
|
|
|
|
|
<span class="badge bg-success">Lu</span>
|
|
|
|
|
{% else %}
|
|
|
|
|
<span class="badge bg-warning">Non lu</span>
|
|
|
|
|
{% endif %}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="card-body">
|
|
|
|
|
<!-- Métadonnées -->
|
|
|
|
|
<div class="row mb-4">
|
|
|
|
|
<div class="col-md-6">
|
|
|
|
|
<h6>Expéditeur</h6>
|
|
|
|
|
<div>
|
|
|
|
|
<strong>{{ mail.sender }}</strong>
|
|
|
|
|
{% if mail.sender_email %}
|
|
|
|
|
<br><small class="text-muted">{{ mail.sender_email }}</small>
|
|
|
|
|
{% endif %}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-6">
|
|
|
|
|
<h6>Date et heure</h6>
|
|
|
|
|
<div>
|
|
|
|
|
{{ mail.received_at.strftime('%d/%m/%Y à %H:%M') }}
|
|
|
|
|
<br><small class="text-muted">Reçu le {{ mail.received_at.strftime('%A, %d %B %Y') }}</small>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- Pièces jointes -->
|
|
|
|
|
{% if mail.has_attachments %}
|
|
|
|
|
<div class="row mb-4">
|
|
|
|
|
<div class="col-12">
|
|
|
|
|
<h6>Pièces jointes ({{ mail.attachment_count }})</h6>
|
|
|
|
|
<div class="alert alert-info">
|
|
|
|
|
<i class="fas fa-paperclip"></i>
|
|
|
|
|
Le téléchargement des pièces jointes n'est pas encore implémenté.
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{% endif %}
|
|
|
|
|
|
|
|
|
|
<!-- Corps du mail -->
|
|
|
|
|
<div class="row">
|
|
|
|
|
<div class="col-12">
|
|
|
|
|
<h6>Corps du mail</h6>
|
|
|
|
|
<div class="border rounded p-3" style="background-color: #f8f9fa;">
|
|
|
|
|
{% if mail.body_content %}
|
|
|
|
|
<pre class="mb-0" style="white-space: pre-wrap; font-family: inherit;">{{ mail.body_content }}</pre>
|
|
|
|
|
{% elif mail.body_preview %}
|
|
|
|
|
<p class="mb-0">{{ mail.body_preview }}</p>
|
|
|
|
|
{% else %}
|
|
|
|
|
<p class="text-muted mb-0">Aucun contenu disponible</p>
|
|
|
|
|
{% endif %}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- Destinataires -->
|
|
|
|
|
<div class="row mt-4">
|
|
|
|
|
<div class="col-md-6">
|
|
|
|
|
<h6>Destinataires</h6>
|
|
|
|
|
<div class="text-muted">
|
|
|
|
|
{% if mail.from_name %}
|
|
|
|
|
De: {{ mail.from_name }} <{{ mail.from_email }}>
|
|
|
|
|
{% endif %}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-6">
|
|
|
|
|
<h6>Actions</h6>
|
|
|
|
|
<div class="btn-group">
|
|
|
|
|
<a href="mailto:{{ mail.sender_email }}" class="btn btn-outline-primary">
|
|
|
|
|
<i class="fas fa-reply"></i> Répondre
|
|
|
|
|
</a>
|
|
|
|
|
<a href="mailto:{{ mail.sender_email }}?subject=Re: {{ mail.subject|replace(' ', '%20') }}" class="btn btn-outline-info">
|
|
|
|
|
<i class="fas fa-reply-all"></i> Répondre à tous
|
|
|
|
|
</a>
|
|
|
|
|
<a href="mailto:?subject={{ mail.subject|replace(' ', '%20') }}" class="btn btn-outline-secondary">
|
|
|
|
|
<i class="fas fa-share"></i> Transférer
|
|
|
|
|
</a>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="card-footer">
|
|
|
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
|
|
|
<small class="text-muted">
|
|
|
|
|
ID du message: {{ mail.message_id }}
|
|
|
|
|
</small>
|
|
|
|
|
<div>
|
|
|
|
|
<button onclick="window.print()" class="btn btn-outline-primary btn-sm">
|
|
|
|
|
<i class="fas fa-print"></i> Imprimer
|
|
|
|
|
</button>
|
|
|
|
|
<button onclick="window.close()" class="btn btn-outline-secondary btn-sm">
|
|
|
|
|
<i class="fas fa-times"></i> Fermer
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- Actions supplémentaires -->
|
|
|
|
|
<div class="row mt-3">
|
|
|
|
|
<div class="col-12">
|
|
|
|
|
<div class="card">
|
|
|
|
|
<div class="card-header">
|
|
|
|
|
<h6 class="mb-0">Actions rapides</h6>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="card-body">
|
|
|
|
|
<div class="row">
|
|
|
|
|
<div class="col-md-3">
|
|
|
|
|
<button class="btn btn-outline-primary w-100" onclick="createIntervention()">
|
|
|
|
|
<i class="fas fa-wrench"></i> Créer une intervention
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-3">
|
|
|
|
|
<button class="btn btn-outline-info w-100" onclick="createEquipment()">
|
|
|
|
|
<i class="fas fa-cogs"></i> Créer un équipement
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-3">
|
|
|
|
|
<button class="btn btn-outline-success w-100" onclick="createNote()">
|
|
|
|
|
<i class="fas fa-sticky-note"></i> Créer une note
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="col-md-3">
|
|
|
|
|
<button class="btn btn-outline-warning w-100" onclick="exportMail()">
|
|
|
|
|
<i class="fas fa-download"></i> Exporter
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- Modal pour créer une intervention -->
|
|
|
|
|
<div class="modal fade" id="interventionModal" tabindex="-1" aria-hidden="true">
|
|
|
|
|
<div class="modal-dialog">
|
|
|
|
|
<div class="modal-content">
|
|
|
|
|
<div class="modal-header">
|
|
|
|
|
<h5 class="modal-title">Créer une intervention depuis cet email</h5>
|
|
|
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-body">
|
|
|
|
|
<form id="interventionForm">
|
|
|
|
|
<div class="mb-3">
|
|
|
|
|
<label for="interventionTitle" class="form-label">Titre de l'intervention</label>
|
|
|
|
|
<input type="text" class="form-control" id="interventionTitle"
|
|
|
|
|
value="Depuis email: {{ mail.subject|truncate(60, true) }}" required>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="mb-3">
|
|
|
|
|
<label for="interventionDescription" class="form-label">Description</label>
|
|
|
|
|
<textarea class="form-control" id="interventionDescription" rows="4" required>
|
|
|
|
|
Email de {{ mail.sender }} ({{ mail.sender_email }}) daté du {{ mail.received_at.strftime('%d/%m/%Y') }}:
|
|
|
|
|
|
|
|
|
|
{{ mail.body_preview|truncate(500, true) }}
|
|
|
|
|
</textarea>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="mb-3">
|
|
|
|
|
<label for="interventionPriority" class="form-label">Priorité</label>
|
|
|
|
|
<select class="form-select" id="interventionPriority">
|
|
|
|
|
<option value="normale">Normale</option>
|
|
|
|
|
<option value="haute">Haute</option>
|
|
|
|
|
<option value="urgente">Urgente</option>
|
|
|
|
|
<option value="basse">Basse</option>
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
</form>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="modal-footer">
|
|
|
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annuler</button>
|
|
|
|
|
<button type="button" class="btn btn-primary" onclick="submitIntervention()">Créer</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{% endblock %}
|
|
|
|
|
|
|
|
|
|
{% block scripts %}
|
|
|
|
|
<script>
|
|
|
|
|
function markAsRead(mailId) {
|
|
|
|
|
fetch(`/outlook/api/mark-read/${mailId}`, {
|
|
|
|
|
method: 'POST'
|
|
|
|
|
})
|
|
|
|
|
.then(response => response.json())
|
|
|
|
|
.then(data => {
|
|
|
|
|
if (data.success) {
|
|
|
|
|
location.reload();
|
|
|
|
|
} else {
|
|
|
|
|
alert('Erreur: ' + data.error);
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch(error => {
|
|
|
|
|
alert('Erreur réseau: ' + error);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function deleteMail(mailId) {
|
|
|
|
|
if (confirm('Supprimer ce mail ?')) {
|
|
|
|
|
fetch(`/outlook/api/delete-mail/${mailId}`, {
|
|
|
|
|
method: 'DELETE'
|
|
|
|
|
})
|
|
|
|
|
.then(response => response.json())
|
|
|
|
|
.then(data => {
|
|
|
|
|
if (data.success) {
|
|
|
|
|
alert('Mail supprimé');
|
|
|
|
|
window.location.href = "{{ url_for('outlook_pages.account_detail', account_id=mail.account_id) }}";
|
|
|
|
|
} else {
|
|
|
|
|
alert('Erreur: ' + data.error);
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch(error => {
|
|
|
|
|
alert('Erreur réseau: ' + error);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createIntervention() {
|
|
|
|
|
const modal = new bootstrap.Modal(document.getElementById('interventionModal'));
|
|
|
|
|
modal.show();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function submitIntervention() {
|
|
|
|
|
const title = document.getElementById('interventionTitle').value;
|
|
|
|
|
const description = document.getElementById('interventionDescription').value;
|
|
|
|
|
const priority = document.getElementById('interventionPriority').value;
|
|
|
|
|
|
|
|
|
|
fetch('/interventions/api/create-from-email', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
headers: {
|
|
|
|
|
'Content-Type': 'application/json'
|
|
|
|
|
},
|
|
|
|
|
body: JSON.stringify({
|
|
|
|
|
title: title,
|
|
|
|
|
description: description,
|
|
|
|
|
priority: priority,
|
|
|
|
|
email_id: {{ mail.id }},
|
|
|
|
|
email_subject: "{{ mail.subject }}",
|
|
|
|
|
email_sender: "{{ mail.sender }}",
|
|
|
|
|
email_date: "{{ mail.received_at.isoformat() }}"
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
.then(response => response.json())
|
|
|
|
|
.then(data => {
|
|
|
|
|
if (data.success) {
|
|
|
|
|
bootstrap.Modal.getInstance(document.getElementById('interventionModal')).hide();
|
|
|
|
|
alert('Intervention créée avec succès !');
|
|
|
|
|
window.location.href = '/interventions';
|
|
|
|
|
} else {
|
|
|
|
|
alert('Erreur: ' + data.error);
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch(error => {
|
|
|
|
|
alert('Erreur réseau: ' + error);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createEquipment() {
|
|
|
|
|
alert('Fonctionnalité à implémenter');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createNote() {
|
|
|
|
|
alert('Fonctionnalité à implémenter');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function exportMail() {
|
|
|
|
|
// Créer un contenu exportable
|
2026-08-15 00:47:55 +02:00
|
|
|
const content = `Email du {{ mail.received_at|datetime_fmt }}
|
2026-08-14 18:02:25 +02:00
|
|
|
De: {{ mail.sender }} ({{ mail.sender_email }})
|
|
|
|
|
Sujet: {{ mail.subject }}
|
|
|
|
|
|
|
|
|
|
{{ mail.body_content|default(mail.body_preview) }}
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const blob = new Blob([content], { type: 'text/plain' });
|
|
|
|
|
const url = URL.createObjectURL(blob);
|
|
|
|
|
const a = document.createElement('a');
|
|
|
|
|
a.href = url;
|
|
|
|
|
a.download = `email_{{ mail.id }}_{{ mail.subject|slugify }}.txt`;
|
|
|
|
|
a.click();
|
|
|
|
|
URL.revokeObjectURL(url);
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
{% endblock %}
|