266 lines
No EOL
12 KiB
HTML
266 lines
No EOL
12 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}Messagerie - GMAO{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container-fluid">
|
|
<div class="page-header">
|
|
<h1 class="h3"><i class="bi bi-envelope-paper"></i> Messagerie unifiee</h1>
|
|
<div>
|
|
<button class="btn btn-primary btn-sm" id="btn-import-outlook">
|
|
<i class="bi bi-cloud-download"></i> Importer 10 emails Outlook
|
|
</button>
|
|
<button class="btn btn-success btn-sm" id="btn-import-ent">
|
|
<i class="bi bi-cloud-download"></i> Importer 10 messages ENT
|
|
</button>
|
|
<button class="btn btn-warning btn-sm" id="btn-interpret-now">
|
|
<i class="bi bi-magic"></i> Interpreter maintenant
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Dernier message importe + derniere interpretation -->
|
|
<div class="row g-2 mb-3">
|
|
<div class="col-md-4">
|
|
<div class="card border-0 shadow-sm h-100">
|
|
<div class="card-body py-2">
|
|
<small class="text-muted d-block"><i class="bi bi-envelope"></i> Dernier mail Outlook</small>
|
|
{% if last_outlook_mail %}
|
|
<strong>{{ last_outlook_mail.subject[:40] }}</strong>
|
|
<br><small class="text-muted">{{ last_outlook_mail.from_name }} - {{ last_outlook_mail.received_at.strftime('%d/%m %H:%M') if last_outlook_mail.received_at else '' }}</small>
|
|
{% else %}
|
|
<span class="text-muted">Aucun mail</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="card border-0 shadow-sm h-100">
|
|
<div class="card-body py-2">
|
|
<small class="text-muted d-block"><i class="bi bi-broadcast"></i> Dernier message ENT</small>
|
|
{% if last_ent_message %}
|
|
<strong>{{ last_ent_message.subject[:40] }}</strong>
|
|
<br><small class="text-muted">{{ last_ent_message.author }} - {{ last_ent_message.received_at.strftime('%d/%m %H:%M') if last_ent_message.received_at else '' }}</small>
|
|
{% else %}
|
|
<span class="text-muted">Aucun message</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="card border-0 shadow-sm h-100">
|
|
<div class="card-body py-2">
|
|
<small class="text-muted d-block"><i class="bi bi-magic"></i> Derniere interpretation</small>
|
|
{% if last_interpretation %}
|
|
<strong>{{ last_interpretation.subject[:40] }}</strong>
|
|
<br><small class="text-muted">{{ last_interpretation.from }} - {{ last_interpretation.date.strftime('%d/%m %H:%M') if last_interpretation.date else '' }}</small>
|
|
{% else %}
|
|
<span class="text-muted">Aucune interpretation</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Interpretations a traiter -->
|
|
<div class="card mb-3 border-warning">
|
|
<div class="card-header bg-warning text-dark">
|
|
<h5 class="mb-0"><i class="bi bi-magic"></i> Interpretations a traiter
|
|
<span class="badge bg-danger ms-2">{{ all_interpretations|length }}</span>
|
|
<small class="ms-2">(Outlook: {{ outlook_count }} | ENT: {{ ent_count }})</small>
|
|
</h5>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
{% if all_interpretations %}
|
|
<div class="table-responsive">
|
|
<table class="table table-hover table-sm mb-0">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>Source</th>
|
|
<th>Date</th>
|
|
<th>Expediteur</th>
|
|
<th>Sujet</th>
|
|
<th>Description suggeree</th>
|
|
<th>Equipement</th>
|
|
<th>Confiance</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for interp in all_interpretations %}
|
|
<tr>
|
|
<td>
|
|
{% if interp.source == 'outlook' %}
|
|
<span class="badge bg-primary"><i class="bi bi-envelope"></i> Outlook</span>
|
|
{% else %}
|
|
<span class="badge bg-info"><i class="bi bi-broadcast"></i> ENT</span>
|
|
{% endif %}
|
|
</td>
|
|
<td class="small">{{ interp.date.strftime('%d/%m %H:%M') if interp.date else '' }}</td>
|
|
<td class="small">{{ interp.from[:25] }}</td>
|
|
<td class="small">{{ interp.subject[:40] }}</td>
|
|
<td class="small text-muted">{{ interp.description[:60] }}</td>
|
|
<td class="small">{{ interp.equipment[:20] }}</td>
|
|
<td>
|
|
{% set conf = (interp.confidence * 100)|round|int %}
|
|
<div class="progress" style="height:6px; width:60px;">
|
|
<div class="progress-bar {% if conf > 70 %}bg-success{% elif conf > 40 %}bg-warning{% else %}bg-danger{% endif %}" style="width:{{ conf }}%"></div>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<a href="{{ interp.create_url }}" class="btn btn-sm btn-success" title="Creer intervention">
|
|
<i class="bi bi-plus-circle"></i>
|
|
</a>
|
|
<a href="{{ interp.detail_url }}" class="btn btn-sm btn-outline-info" title="Voir detail">
|
|
<i class="bi bi-eye"></i>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% else %}
|
|
<div class="empty-state py-4">
|
|
<i class="bi bi-check-circle"></i>
|
|
<p>Aucune interpretation en attente</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<!-- 10 derniers messages Outlook -->
|
|
<div class="col-md-6">
|
|
<div class="card">
|
|
<div class="card-header bg-primary text-white">
|
|
<h6 class="mb-0"><i class="bi bi-envelope"></i> 10 derniers emails Outlook</h6>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
{% if outlook_mails %}
|
|
<div class="list-group list-group-flush">
|
|
{% for mail in outlook_mails %}
|
|
<div class="list-group-item {% if not mail.is_read %}fw-bold{% endif %}">
|
|
<div class="d-flex justify-content-between align-items-start">
|
|
<div>
|
|
<small class="text-muted">{{ mail.from_name }}</small>
|
|
<div>{{ mail.subject[:60] }}</div>
|
|
{% if mail.has_interpretation %}
|
|
<span class="badge bg-success badge-sm"><i class="bi bi-magic"></i> interprete</span>
|
|
{% endif %}
|
|
</div>
|
|
<small class="text-muted">{{ mail.received_at.strftime('%d/%m %H:%M') if mail.received_at else '' }}</small>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% else %}
|
|
<div class="empty-state py-4">
|
|
<i class="bi bi-envelope"></i>
|
|
<p>Aucun email Outlook importe</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 10 derniers messages ENT -->
|
|
<div class="col-md-6">
|
|
<div class="card">
|
|
<div class="card-header bg-info text-white">
|
|
<h6 class="mb-0"><i class="bi bi-broadcast"></i> 10 derniers messages ENT</h6>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
{% if ent_messages %}
|
|
<div class="list-group list-group-flush">
|
|
{% for msg in ent_messages %}
|
|
<div class="list-group-item">
|
|
<div class="d-flex justify-content-between align-items-start">
|
|
<div>
|
|
<small class="text-muted">{{ msg.author }}</small>
|
|
<div>{{ msg.subject[:60] }}</div>
|
|
{% if msg.has_interpretation %}
|
|
<span class="badge bg-success badge-sm"><i class="bi bi-magic"></i> interprete</span>
|
|
{% endif %}
|
|
</div>
|
|
<small class="text-muted">{{ msg.received_at.strftime('%d/%m %H:%M') if msg.received_at else '' }}</small>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% else %}
|
|
<div class="empty-state py-4">
|
|
<i class="bi bi-broadcast"></i>
|
|
<p>Aucun message ENT importe</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.getElementById('btn-import-outlook').addEventListener('click', async function() {
|
|
const btn = this;
|
|
const original = btn.innerHTML;
|
|
btn.disabled = true;
|
|
btn.innerHTML = '<span class="gmao-spinner"></span> Importation...';
|
|
try {
|
|
const r = await fetch('/messagerie/api/import-outlook', {method: 'POST'});
|
|
const d = await r.json();
|
|
if (d.success) {
|
|
alert(d.message);
|
|
location.reload();
|
|
} else {
|
|
alert('Erreur: ' + (d.error || 'Echec de l\'import'));
|
|
}
|
|
} catch(e) {
|
|
alert('Erreur: ' + e.message);
|
|
}
|
|
btn.disabled = false;
|
|
btn.innerHTML = original;
|
|
});
|
|
|
|
document.getElementById('btn-import-ent').addEventListener('click', async function() {
|
|
const btn = this;
|
|
const original = btn.innerHTML;
|
|
btn.disabled = true;
|
|
btn.innerHTML = '<span class="gmao-spinner"></span> Importation...';
|
|
try {
|
|
const r = await fetch('/messagerie/api/import-ent', {method: 'POST'});
|
|
const d = await r.json();
|
|
if (d.success) {
|
|
alert(d.message);
|
|
location.reload();
|
|
} else {
|
|
alert('Erreur: ' + (d.error || 'Echec de l\'import'));
|
|
}
|
|
} catch(e) {
|
|
alert('Erreur: ' + e.message);
|
|
}
|
|
btn.disabled = false;
|
|
btn.innerHTML = original;
|
|
});
|
|
|
|
document.getElementById('btn-interpret-now').addEventListener('click', async function() {
|
|
const btn = this;
|
|
const original = btn.innerHTML;
|
|
btn.disabled = true;
|
|
btn.innerHTML = '<span class="gmao-spinner"></span> Interpretation...';
|
|
try {
|
|
const r = await fetch('/messagerie/api/interpret-now', {method: 'POST'});
|
|
const d = await r.json();
|
|
if (d.success) {
|
|
alert(d.message);
|
|
location.reload();
|
|
} else {
|
|
alert('Erreur: ' + (d.error || 'Echec de l\'interpretation'));
|
|
}
|
|
} catch(e) {
|
|
alert('Erreur: ' + e.message);
|
|
}
|
|
btn.disabled = false;
|
|
btn.innerHTML = original;
|
|
});
|
|
</script>
|
|
{% endblock %} |