263 lines
15 KiB
HTML
263 lines
15 KiB
HTML
{% load i18n %}
|
|
|
|
{# Interventions liées à l'asset #}
|
|
<div class="card mb-3" id="asset-interventions-card">
|
|
<div class="card-header bg-light d-flex align-items-center justify-content-between">
|
|
<h5 class="mb-0">
|
|
<i class="bi bi-wrench-adjustable me-2"></i>{% translate "Interventions liées" %}
|
|
{% if interventions %}
|
|
<span class="badge bg-secondary rounded-pill ms-1">{{ interventions|length }}</span>
|
|
{% endif %}
|
|
</h5>
|
|
{% if can_add_intervention %}
|
|
<button type="button" class="btn btn-outline-primary btn-sm" data-bs-toggle="modal" data-bs-target="#createInterventionForAssetModal">
|
|
<i class="bi bi-plus-lg me-1"></i>{% translate "Créer une intervention" %}
|
|
</button>
|
|
{% endif %}
|
|
</div>
|
|
<div class="card-body p-0">
|
|
{% if interventions %}
|
|
<div class="table-responsive">
|
|
<table class="table table-hover table-sm mb-0 align-middle">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th style="width: 12%;" class="ps-3">{% translate "Code" %}</th>
|
|
<th style="width: 25%;">{% translate "Titre" %}</th>
|
|
<th style="width: 18%;">{% translate "Symptôme" %}</th>
|
|
<th style="width: 15%;">{% translate "Statut" %}</th>
|
|
<th style="width: 10%;">{% translate "Priorité" %}</th>
|
|
<th style="width: 12%;">{% translate "Attribué à" %}</th>
|
|
<th style="width: 8%;" class="pe-3">{% translate "Date" %}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for intervention in interventions %}
|
|
<tr>
|
|
<td class="ps-3">
|
|
<a href="{% url 'interventions:intervention_detail' intervention.id %}" class="fw-bold text-decoration-none">
|
|
{{ intervention.code }}
|
|
</a>
|
|
</td>
|
|
<td>
|
|
<a href="{% url 'interventions:intervention_detail' intervention.id %}" class="text-reset text-decoration-none">
|
|
{{ intervention.title }}
|
|
</a>
|
|
{% if intervention.maintain_type == 'corrective' %}
|
|
<span class="badge bg-danger ms-1" title="{% translate 'Maintenance corrective' %}">{% translate "Corrective" %}</span>
|
|
{% elif intervention.maintain_type == 'preventive' %}
|
|
<span class="badge bg-warning text-dark ms-1" title="{% translate 'Maintenance préventive' %}">{% translate "Préventive" %}</span>
|
|
{% elif intervention.maintain_type == 'ameliorative' %}
|
|
<span class="badge bg-success ms-1" title="{% translate 'Maintenance améliorative' %}">{% translate "Améliorative" %}</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
{% if intervention.symptom %}
|
|
{{ intervention.symptom.get_name }}
|
|
{% else %}
|
|
<span class="text-muted">-</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
<span class="badge" style="background-color: {{ intervention.status_color_hex }}; color: {{ intervention.status_text_color_hex }};">
|
|
{{ intervention.get_status_display }}
|
|
</span>
|
|
</td>
|
|
<td>
|
|
{% if intervention.priority == '1' %}
|
|
<span class="badge bg-danger">{{ intervention.get_priority_display }}</span>
|
|
{% elif intervention.priority == '2' %}
|
|
<span class="badge bg-warning text-dark">{{ intervention.get_priority_display }}</span>
|
|
{% elif intervention.priority == '3' %}
|
|
<span class="badge bg-secondary">{{ intervention.get_priority_display }}</span>
|
|
{% elif intervention.priority == '4' %}
|
|
<span class="badge bg-light text-dark border">{{ intervention.get_priority_display }}</span>
|
|
{% else %}
|
|
<span class="badge bg-secondary">{{ intervention.get_priority_display|default:"-" }}</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
{% if intervention.assigned_team %}
|
|
<span class="small">{{ intervention.assigned_team.name }}</span>
|
|
{% elif intervention.assigned_provider %}
|
|
<span class="small">{{ intervention.assigned_provider.name }}</span>
|
|
{% else %}
|
|
<span class="text-muted small">-</span>
|
|
{% endif %}
|
|
</td>
|
|
<td class="pe-3">
|
|
<small class="text-muted">{{ intervention.creation_time|date:"d/m/Y" }}</small>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% else %}
|
|
<div class="p-3 text-muted">
|
|
<i class="bi bi-info-circle me-1"></i>{% translate "Aucune intervention liée à cet asset." %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
{% if can_add_intervention %}
|
|
<!-- Modal de création d'une intervention depuis l'asset -->
|
|
<div class="modal fade" id="createInterventionForAssetModal" tabindex="-1" aria-labelledby="createInterventionForAssetModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content">
|
|
<div class="modal-header bg-light">
|
|
<h5 class="modal-title" id="createInterventionForAssetModalLabel">
|
|
<i class="bi bi-wrench-adjustable me-2"></i>{% translate "Nouvelle intervention" %}
|
|
</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% translate 'Fermer' %}"></button>
|
|
</div>
|
|
<form id="createInterventionForAssetForm" action="{% url 'assets:create_intervention_for_asset' asset_model asset.id %}" method="post">
|
|
{% csrf_token %}
|
|
<div class="modal-body">
|
|
<div id="createInterventionAlert" class="alert alert-danger d-none mb-3"></div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label fw-semibold required">{% translate "Titre" %}</label>
|
|
<input type="text" name="title" class="form-control" placeholder="{% translate "Titre de l'intervention" %}" required>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label fw-semibold">{% translate "Symptôme" %}</label>
|
|
<select name="symptom_id" id="asset_intervention_symptom_select" class="form-select">
|
|
<option value="">{% translate "-- Sélectionner un symptôme --" %}</option>
|
|
{% for s in symptoms %}
|
|
<option value="{{ s.id }}" data-name="{{ s.get_name }}" data-priority="{{ s.priority|default:'3' }}">{{ s.get_name }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label fw-semibold d-block">{% translate "Type de maintenance" %}</label>
|
|
<div class="btn-group w-100" role="group" aria-label="{% translate 'Type de maintenance' %}">
|
|
<input type="radio" class="btn-check" name="maintain_type" id="maintain_type_corrective" value="corrective" checked>
|
|
<label class="btn btn-outline-danger d-flex align-items-center justify-content-center gap-1 py-2" for="maintain_type_corrective">
|
|
<i class="bi bi-wrench"></i>
|
|
<span>{% translate "Corrective" %}</span>
|
|
</label>
|
|
|
|
<input type="radio" class="btn-check" name="maintain_type" id="maintain_type_preventive" value="preventive">
|
|
<label class="btn btn-outline-warning text-dark d-flex align-items-center justify-content-center gap-1 py-2" for="maintain_type_preventive">
|
|
<i class="bi bi-shield-check"></i>
|
|
<span>{% translate "Préventive" %}</span>
|
|
</label>
|
|
|
|
<input type="radio" class="btn-check" name="maintain_type" id="maintain_type_ameliorative" value="ameliorative">
|
|
<label class="btn btn-outline-success d-flex align-items-center justify-content-center gap-1 py-2" for="maintain_type_ameliorative">
|
|
<i class="bi bi-arrow-up-circle"></i>
|
|
<span>{% translate "Améliorative" %}</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label fw-semibold">{% translate "Priorité" %}</label>
|
|
<select name="priority" id="asset_intervention_priority_select" class="form-select">
|
|
<option value="1">{% translate "Urgent" %}</option>
|
|
<option value="2">{% translate "Élevé" %}</option>
|
|
<option value="3" selected>{% translate "Normal" %}</option>
|
|
<option value="4">{% translate "Bas" %}</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label fw-semibold">{% translate "Description / Remarques" %}</label>
|
|
<textarea name="init_description" class="form-control" rows="3" placeholder="{% translate 'Détails ou remarques initiales...' %}"></textarea>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer bg-light">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{% translate "Annuler" %}</button>
|
|
<button type="submit" class="btn btn-primary" id="submitCreateInterventionBtn">
|
|
<span class="spinner-border spinner-border-sm me-1 d-none" id="submitCreateInterventionSpinner" role="status"></span>
|
|
<i class="bi bi-check-circle me-1" id="submitCreateInterventionIcon"></i>{% translate "Créer" %}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
(function() {
|
|
const form = document.getElementById('createInterventionForAssetForm');
|
|
if (!form) return;
|
|
|
|
const symptomSelect = document.getElementById('asset_intervention_symptom_select');
|
|
const titleInput = form.querySelector('input[name="title"]');
|
|
const prioritySelect = document.getElementById('asset_intervention_priority_select');
|
|
let lastAutoTitle = '';
|
|
|
|
if (symptomSelect && titleInput) {
|
|
symptomSelect.addEventListener('change', function() {
|
|
const selectedOpt = symptomSelect.options[symptomSelect.selectedIndex];
|
|
if (selectedOpt && selectedOpt.value) {
|
|
const symName = selectedOpt.getAttribute('data-name') || selectedOpt.text.trim();
|
|
const symPriority = selectedOpt.getAttribute('data-priority');
|
|
|
|
if (!titleInput.value || titleInput.value === lastAutoTitle) {
|
|
titleInput.value = symName;
|
|
lastAutoTitle = symName;
|
|
}
|
|
|
|
if (symPriority && prioritySelect) {
|
|
prioritySelect.value = symPriority;
|
|
}
|
|
}
|
|
});
|
|
|
|
titleInput.addEventListener('input', function() {
|
|
if (titleInput.value !== lastAutoTitle) {
|
|
lastAutoTitle = '';
|
|
}
|
|
});
|
|
}
|
|
|
|
form.addEventListener('submit', function(e) {
|
|
e.preventDefault();
|
|
const alertDiv = document.getElementById('createInterventionAlert');
|
|
const submitBtn = document.getElementById('submitCreateInterventionBtn');
|
|
const spinner = document.getElementById('submitCreateInterventionSpinner');
|
|
const icon = document.getElementById('submitCreateInterventionIcon');
|
|
|
|
alertDiv.classList.add('d-none');
|
|
alertDiv.textContent = '';
|
|
submitBtn.disabled = true;
|
|
if (spinner) spinner.classList.remove('d-none');
|
|
if (icon) icon.classList.add('d-none');
|
|
|
|
const formData = new FormData(form);
|
|
|
|
fetch(form.action, {
|
|
method: 'POST',
|
|
body: formData,
|
|
headers: {
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
}
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success && data.redirect_url) {
|
|
window.location.href = data.redirect_url;
|
|
} else {
|
|
alertDiv.textContent = data.error || '{% translate "Une erreur est survenue." %}';
|
|
alertDiv.classList.remove('d-none');
|
|
submitBtn.disabled = false;
|
|
if (spinner) spinner.classList.add('d-none');
|
|
if (icon) icon.classList.remove('d-none');
|
|
}
|
|
})
|
|
.catch(err => {
|
|
alertDiv.textContent = '{% translate "Erreur réseau lors de la création." %}';
|
|
alertDiv.classList.remove('d-none');
|
|
submitBtn.disabled = false;
|
|
if (spinner) spinner.classList.add('d-none');
|
|
if (icon) icon.classList.remove('d-none');
|
|
});
|
|
});
|
|
})();
|
|
</script>
|
|
{% endif %}
|