fix(inspections): fix mobile zone filter and complete mobile translations in lists and maps

This commit is contained in:
kdeterme 2026-09-23 16:57:41 +02:00
parent 61ef7fc3ea
commit 6b526f7056
26 changed files with 644 additions and 77 deletions

View file

@ -613,3 +613,107 @@ msgstr "Collapse models"
#: loko/assets/static/assets/unified_index.js:3726
msgid "Bloc replié. Cliquez sur \"Afficher les modèles\" pour voir les options."
msgstr ""
#: loko/assets/static/assets/inspection_map.js:93
msgid "Rechercher une adresse…"
msgstr "Search an address…"
msgid "Rechercher une adresse..."
msgstr "Search an address..."
#: loko/assets/static/assets/inspection_map.js:748
msgid "Géolocalisation..."
msgstr "Geolocation..."
#: loko/assets/static/assets/inspection_map.js:769
msgid "Position actualisée"
msgstr "Position updated"
#: loko/assets/static/assets/inspection_map.js:773
msgid "GPS indisponible"
msgstr "GPS unavailable"
#: loko/assets/static/assets/inspection_map.js:935
msgid "Inspections (Désactivé)"
msgstr "Inspections (Disabled)"
#: loko/assets/static/assets/inspection_map.js:936
msgid "Inspections (1 mois)"
msgstr "Inspections (1 month)"
#: loko/assets/static/assets/inspection_map.js:937
msgid "Inspections (3 mois)"
msgstr "Inspections (3 months)"
#: loko/assets/static/assets/inspection_map.js:938
msgid "Inspections (6 mois)"
msgstr "Inspections (6 months)"
#: loko/assets/static/assets/inspection_map.js:939
msgid "Inspections (1 an)"
msgstr "Inspections (1 year)"
#: loko/assets/static/assets/inspection_map.js:940
msgid "Inspections (Tout)"
msgstr "Inspections (All)"
msgid "Panneau"
msgstr "Sign"
msgid "Supprimer ce panneau"
msgstr "Delete this sign"
msgid "Mention (ex: Sauf riverains)"
msgstr "Mention (e.g. Except local traffic)"
msgid "Propreté :"
msgstr "Cleanliness:"
msgid "Propre"
msgstr "Clean"
msgid "Sale"
msgstr "Dirty"
msgid "Végétation"
msgstr "Vegetation"
msgid "Dégradé"
msgstr "Damaged"
msgid "Coordonnées GPS manquantes."
msgstr "Missing GPS coordinates."
msgid "Veuillez ajouter au moins un panneau."
msgstr "Please add at least one sign."
msgid "Panneaux créés avec succès !"
msgstr "Signs created successfully!"
msgid "Erreur : "
msgstr "Error: "
msgid "Impossible de créer les panneaux."
msgstr "Unable to create signs."
msgid "Erreur lors de la création : "
msgstr "Error during creation: "
msgid "Créer et Enregistrer"
msgstr "Create and Save"
msgid "Inspection enregistrée !"
msgstr "Inspection saved!"
msgid "Intervention"
msgstr "Intervention"
msgid "créée."
msgstr "created."
msgid "Erreur lors de la validation."
msgstr "Validation error."
msgid "Erreur réseau."
msgstr "Network error."

View file

@ -618,3 +618,107 @@ msgstr "Replier les modèles"
#: loko/assets/static/assets/unified_index.js:3726
msgid "Bloc replié. Cliquez sur \"Afficher les modèles\" pour voir les options."
msgstr "Bloc replié. Cliquez sur \"Afficher les modèles\" pour voir les options."
#: loko/assets/static/assets/inspection_map.js:93
msgid "Rechercher une adresse…"
msgstr "Rechercher une adresse…"
msgid "Rechercher une adresse..."
msgstr "Rechercher une adresse..."
#: loko/assets/static/assets/inspection_map.js:748
msgid "Géolocalisation..."
msgstr "Géolocalisation..."
#: loko/assets/static/assets/inspection_map.js:769
msgid "Position actualisée"
msgstr "Position actualisée"
#: loko/assets/static/assets/inspection_map.js:773
msgid "GPS indisponible"
msgstr "GPS indisponible"
#: loko/assets/static/assets/inspection_map.js:935
msgid "Inspections (Désactivé)"
msgstr "Inspections (Désactivé)"
#: loko/assets/static/assets/inspection_map.js:936
msgid "Inspections (1 mois)"
msgstr "Inspections (1 mois)"
#: loko/assets/static/assets/inspection_map.js:937
msgid "Inspections (3 mois)"
msgstr "Inspections (3 mois)"
#: loko/assets/static/assets/inspection_map.js:938
msgid "Inspections (6 mois)"
msgstr "Inspections (6 mois)"
#: loko/assets/static/assets/inspection_map.js:939
msgid "Inspections (1 an)"
msgstr "Inspections (1 an)"
#: loko/assets/static/assets/inspection_map.js:940
msgid "Inspections (Tout)"
msgstr "Inspections (Tout)"
msgid "Panneau"
msgstr "Panneau"
msgid "Supprimer ce panneau"
msgstr "Supprimer ce panneau"
msgid "Mention (ex: Sauf riverains)"
msgstr "Mention (ex: Sauf riverains)"
msgid "Propreté :"
msgstr "Propreté :"
msgid "Propre"
msgstr "Propre"
msgid "Sale"
msgstr "Sale"
msgid "Végétation"
msgstr "Végétation"
msgid "Dégradé"
msgstr "Dégradé"
msgid "Coordonnées GPS manquantes."
msgstr "Coordonnées GPS manquantes."
msgid "Veuillez ajouter au moins un panneau."
msgstr "Veuillez ajouter au moins un panneau."
msgid "Panneaux créés avec succès !"
msgstr "Panneaux créés avec succès !"
msgid "Erreur : "
msgstr "Erreur : "
msgid "Impossible de créer les panneaux."
msgstr "Impossible de créer les panneaux."
msgid "Erreur lors de la création : "
msgstr "Erreur lors de la création : "
msgid "Créer et Enregistrer"
msgstr "Créer et Enregistrer"
msgid "Inspection enregistrée !"
msgstr "Inspection enregistrée !"
msgid "Intervention"
msgstr "Intervention"
msgid "créée."
msgstr "créée."
msgid "Erreur lors de la validation."
msgstr "Erreur lors de la validation."
msgid "Erreur réseau."
msgstr "Erreur réseau."

View file

@ -615,3 +615,107 @@ msgstr "Modellen inklappen"
#: loko/assets/static/assets/unified_index.js:3726
msgid "Bloc replié. Cliquez sur \"Afficher les modèles\" pour voir les options."
msgstr ""
#: loko/assets/static/assets/inspection_map.js:93
msgid "Rechercher une adresse…"
msgstr "Zoek een adres…"
msgid "Rechercher une adresse..."
msgstr "Zoek een adres..."
#: loko/assets/static/assets/inspection_map.js:748
msgid "Géolocalisation..."
msgstr "Geolocatie..."
#: loko/assets/static/assets/inspection_map.js:769
msgid "Position actualisée"
msgstr "Positie bijgewerkt"
#: loko/assets/static/assets/inspection_map.js:773
msgid "GPS indisponible"
msgstr "GPS niet beschikbaar"
#: loko/assets/static/assets/inspection_map.js:935
msgid "Inspections (Désactivé)"
msgstr "Inspecties (Uitgeschakeld)"
#: loko/assets/static/assets/inspection_map.js:936
msgid "Inspections (1 mois)"
msgstr "Inspecties (1 maand)"
#: loko/assets/static/assets/inspection_map.js:937
msgid "Inspections (3 mois)"
msgstr "Inspecties (3 maanden)"
#: loko/assets/static/assets/inspection_map.js:938
msgid "Inspections (6 mois)"
msgstr "Inspecties (6 maanden)"
#: loko/assets/static/assets/inspection_map.js:939
msgid "Inspections (1 an)"
msgstr "Inspecties (1 jaar)"
#: loko/assets/static/assets/inspection_map.js:940
msgid "Inspections (Tout)"
msgstr "Inspecties (Alles)"
msgid "Panneau"
msgstr "Bord"
msgid "Supprimer ce panneau"
msgstr "Dit bord verwijderen"
msgid "Mention (ex: Sauf riverains)"
msgstr "Vermelding (bijv. Uitgezonderd aangelanden)"
msgid "Propreté :"
msgstr "Netheid:"
msgid "Propre"
msgstr "Schoon"
msgid "Sale"
msgstr "Vuil"
msgid "Végétation"
msgstr "Vegetatie"
msgid "Dégradé"
msgstr "Beschadigd"
msgid "Coordonnées GPS manquantes."
msgstr "Ontbrekende gps-coördinaten."
msgid "Veuillez ajouter au moins un panneau."
msgstr "Voeg minimaal één bord toe."
msgid "Panneaux créés avec succès !"
msgstr "Borden succesvol aangemaakt!"
msgid "Erreur : "
msgstr "Fout: "
msgid "Impossible de créer les panneaux."
msgstr "Kan de borden niet aanmaken."
msgid "Erreur lors de la création : "
msgstr "Fout bij aanmaken: "
msgid "Créer et Enregistrer"
msgstr "Aanmaken en opslaan"
msgid "Inspection enregistrée !"
msgstr "Inspectie opgeslagen!"
msgid "Intervention"
msgstr "Interventie"
msgid "créée."
msgstr "aangemaakt."
msgid "Erreur lors de la validation."
msgstr "Fout bij validatie."
msgid "Erreur réseau."
msgstr "Netwerkfout."

View file

@ -89,9 +89,11 @@
if (typeof AddressSearchControl !== 'undefined') {
const autocompleteUrl = window.AUTOCOMPLETE_STREET_URL || '/common/autocomplete-street/';
const i18n = window.INSPECTION_MAP_I18N || {};
const placeholder = i18n.searchAddress || (typeof gettext !== 'undefined' ? gettext('Rechercher une adresse…') : 'Rechercher une adresse…');
const searchCtrl = new AddressSearchControl({
autocompleteUrl: autocompleteUrl,
placeholder: 'Rechercher une adresse...'
placeholder: placeholder
});
map.addControl(searchCtrl, 'top-left');
}
@ -744,8 +746,9 @@
function locateUser() {
if (!navigator.geolocation) return;
const i18n = window.INSPECTION_MAP_I18N || {};
const statusText = document.getElementById('gps-status-text');
if (statusText) statusText.textContent = 'Géolocalisation...';
if (statusText) statusText.textContent = i18n.geolocation || (typeof gettext !== 'undefined' ? gettext('Géolocalisation...') : 'Géolocalisation...');
navigator.geolocation.getCurrentPosition(
function(position) {
@ -766,11 +769,11 @@
map.flyTo({ center: [lng, lat], zoom: 17 });
}
if (statusText) statusText.textContent = 'Position actualisée';
if (statusText) statusText.textContent = i18n.positionUpdated || (typeof gettext !== 'undefined' ? gettext('Position actualisée') : 'Position actualisée');
},
function(err) {
console.warn('GPS error:', err.message);
if (statusText) statusText.textContent = 'GPS indisponible';
if (statusText) statusText.textContent = i18n.gpsUnavailable || (typeof gettext !== 'undefined' ? gettext('GPS indisponible') : 'GPS indisponible');
},
{ enableHighAccuracy: true, timeout: 10000, maximumAge: 5000 }
);
@ -931,13 +934,17 @@
const STORAGE_HISTORY_PERIOD_KEY = 'loko_insp_history_period';
function getHistoryPeriodLabels() {
const i18n = window.INSPECTION_MAP_I18N || {};
if (i18n.periodLabels) {
return i18n.periodLabels;
}
return {
'disabled': 'Inspections (Désactivé)',
'1m': 'Inspections (1 mois)',
'3m': 'Inspections (3 mois)',
'6m': 'Inspections (6 mois)',
'1y': 'Inspections (1 an)',
'all': 'Inspections (Tout)'
'disabled': (typeof gettext !== 'undefined' ? gettext('Inspections (Désactivé)') : 'Inspections (Désactivé)'),
'1m': (typeof gettext !== 'undefined' ? gettext('Inspections (1 mois)') : 'Inspections (1 mois)'),
'3m': (typeof gettext !== 'undefined' ? gettext('Inspections (3 mois)') : 'Inspections (3 mois)'),
'6m': (typeof gettext !== 'undefined' ? gettext('Inspections (6 mois)') : 'Inspections (6 mois)'),
'1y': (typeof gettext !== 'undefined' ? gettext('Inspections (1 an)') : 'Inspections (1 an)'),
'all': (typeof gettext !== 'undefined' ? gettext('Inspections (Tout)') : 'Inspections (Tout)')
};
}
@ -959,7 +966,7 @@
}
});
if (labelEl) labelEl.textContent = labels[period] || 'Inspections (3 mois)';
if (labelEl) labelEl.textContent = labels[period] || labels['3m'] || (typeof gettext !== 'undefined' ? gettext('Inspections (3 mois)') : 'Inspections (3 mois)');
if (iconEl) {
if (period === 'disabled') {
iconEl.className = 'bi bi-eye-slash text-muted me-1';
@ -1980,9 +1987,9 @@
row.innerHTML = `
<div class="d-flex align-items-center justify-content-between mb-2">
<span class="badge bg-primary rounded-pill small">#${order} (${labelFr || 'Panneau'})</span>
<span class="badge bg-primary rounded-pill small">#${order} (${labelFr || (window.gettext ? window.gettext('Panneau') : 'Panneau')})</span>
${confidence ? `<span class="badge bg-success-subtle text-success border border-success-subtle extra-small">IA: ${Math.round(confidence * 100)}%</span>` : ''}
<button type="button" class="btn btn-outline-danger btn-xs py-0 px-1.5 btn-remove-panel-row" style="font-size: 0.75rem;" title="Supprimer ce panneau">
<button type="button" class="btn btn-outline-danger btn-xs py-0 px-1.5 btn-remove-panel-row" style="font-size: 0.75rem;" title="${window.gettext ? window.gettext('Supprimer ce panneau') : 'Supprimer ce panneau'}">
<i class="bi bi-trash"></i>
</button>
</div>
@ -1994,23 +2001,23 @@
</div>
<div class="col">
<div class="input-group input-group-sm mb-1">
<span class="input-group-text fw-bold">Code</span>
<span class="input-group-text fw-bold">${window.gettext ? window.gettext('Code') : 'Code'}</span>
<input type="text" class="form-control form-control-sm text-uppercase panel-row-code" value="${upperCode}" placeholder="Ex: C1, D7, B1, M2...">
</div>
<input type="text" class="form-control form-control-sm panel-row-text" value="${text || ''}" placeholder="Mention (ex: Sauf riverains)">
<input type="text" class="form-control form-control-sm panel-row-text" value="${text || ''}" placeholder="${window.gettext ? window.gettext('Mention (ex: Sauf riverains)') : 'Mention (ex: Sauf riverains)'}">
</div>
</div>
<div class="mt-2 pt-1 border-top d-flex align-items-center justify-content-between">
<small class="text-muted extra-small">Propreté :</small>
<small class="text-muted extra-small">${window.gettext ? window.gettext('Propreté :') : 'Propreté :'}</small>
<div class="btn-group btn-group-sm" role="group">
<input type="radio" class="btn-check panel-row-clean" name="row_clean_${order}_${Date.now()}" id="rc_clean_${order}_${Date.now()}" value="clean" ${cleanliness === 'clean' ? 'checked' : ''}>
<label class="btn btn-outline-success btn-xs py-0 px-2" for="rc_clean_${order}_${Date.now()}">Propre</label>
<label class="btn btn-outline-success btn-xs py-0 px-2" for="rc_clean_${order}_${Date.now()}">${window.gettext ? window.gettext('Propre') : 'Propre'}</label>
<input type="radio" class="btn-check panel-row-clean" name="row_clean_${order}_${Date.now()}" id="rc_dirty_${order}_${Date.now()}" value="dirty" ${cleanliness === 'dirty' ? 'checked' : ''}>
<label class="btn btn-outline-warning btn-xs py-0 px-2" for="rc_dirty_${order}_${Date.now()}">Sale</label>
<label class="btn btn-outline-warning btn-xs py-0 px-2" for="rc_dirty_${order}_${Date.now()}">${window.gettext ? window.gettext('Sale') : 'Sale'}</label>
<input type="radio" class="btn-check panel-row-clean" name="row_clean_${order}_${Date.now()}" id="rc_veg_${order}_${Date.now()}" value="vegetation" ${cleanliness === 'vegetation' ? 'checked' : ''}>
<label class="btn btn-outline-warning btn-xs py-0 px-2" for="rc_veg_${order}_${Date.now()}">Végétation</label>
<label class="btn btn-outline-warning btn-xs py-0 px-2" for="rc_veg_${order}_${Date.now()}">${window.gettext ? window.gettext('Végétation') : 'Végétation'}</label>
<input type="radio" class="btn-check panel-row-clean" name="row_clean_${order}_${Date.now()}" id="rc_vand_${order}_${Date.now()}" value="vandalized" ${cleanliness === 'vandalized' ? 'checked' : ''}>
<label class="btn btn-outline-danger btn-xs py-0 px-2" for="rc_vand_${order}_${Date.now()}">Dégradé</label>
<label class="btn btn-outline-danger btn-xs py-0 px-2" for="rc_vand_${order}_${Date.now()}">${window.gettext ? window.gettext('Dégradé') : 'Dégradé'}</label>
</div>
</div>
`;
@ -2043,13 +2050,13 @@
const lon = document.getElementById('new_sign_lon')?.value;
if (!lat || !lon) {
alert('Coordonnées GPS manquantes.');
alert(window.gettext ? window.gettext('Coordonnées GPS manquantes.') : 'Coordonnées GPS manquantes.');
return;
}
const rows = document.querySelectorAll('.new-sign-panel-row');
if (!rows.length) {
alert('Veuillez ajouter au moins un panneau.');
alert(window.gettext ? window.gettext('Veuillez ajouter au moins un panneau.') : 'Veuillez ajouter au moins un panneau.');
return;
}
@ -2074,7 +2081,8 @@
newSignPhotos.forEach(p => formData.append('photos', p));
btnSubmit.disabled = true;
btnSubmit.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span> Création en cours...';
const creatingMsg = window.gettext ? window.gettext('Création en cours...') : 'Création en cours...';
btnSubmit.innerHTML = `<span class="spinner-border spinner-border-sm me-1"></span> ${creatingMsg}`;
try {
const csrfToken = getCsrfToken();
@ -2095,7 +2103,7 @@
if (data.success) {
modal.hide();
alert(data.message || 'Panneaux créés avec succès !');
alert(data.message || (window.gettext ? window.gettext('Panneaux créés avec succès !') : 'Panneaux créés avec succès !'));
// Basculer automatiquement sur la thématique Signalisation
localStorage.setItem(STORAGE_THEMATIC_KEY, 'sign');
@ -2113,13 +2121,17 @@
loadAssets();
loadInspectionsHistory();
} else {
alert('Erreur : ' + (data.message || 'Impossible de créer les panneaux.'));
const errPrefix = window.gettext ? window.gettext('Erreur : ') : 'Erreur : ';
const defaultErrMsg = window.gettext ? window.gettext('Impossible de créer les panneaux.') : 'Impossible de créer les panneaux.';
alert(errPrefix + (data.message || defaultErrMsg));
}
} catch(err) {
alert('Erreur lors de la création : ' + err.message);
const errCreationMsg = window.gettext ? window.gettext('Erreur lors de la création : ') : 'Erreur lors de la création : ';
alert(errCreationMsg + err.message);
} finally {
btnSubmit.disabled = false;
btnSubmit.innerHTML = '<i class="bi bi-check2-circle fs-6"></i> <span>Créer et Enregistrer</span>';
const createAndSaveMsg = window.gettext ? window.gettext('Créer et Enregistrer') : 'Créer et Enregistrer';
btnSubmit.innerHTML = `<i class="bi bi-check2-circle fs-6"></i> <span>${createAndSaveMsg}</span>`;
}
});
}
@ -2176,19 +2188,22 @@
const modal = bootstrap.Modal.getInstance(modalEl);
if (modal) modal.hide();
let msg = data.message || 'Inspection enregistrée !';
let msg = data.message || (window.gettext ? window.gettext('Inspection enregistrée !') : 'Inspection enregistrée !');
if (data.created_intervention_code) {
msg += ' Intervention ' + data.created_intervention_code + ' créée.';
const intervLabel = window.gettext ? window.gettext('Intervention') : 'Intervention';
const createdLabel = window.gettext ? window.gettext('créée.') : 'créée.';
msg += ` ${intervLabel} ${data.created_intervention_code} ${createdLabel}`;
}
alert(msg);
loadAssets();
} else {
alertDiv.textContent = data.error || 'Erreur lors de la validation.';
const defaultValError = window.gettext ? window.gettext('Erreur lors de la validation.') : 'Erreur lors de la validation.';
alertDiv.textContent = data.error || defaultValError;
alertDiv.classList.remove('d-none');
}
})
.catch(err => {
alertDiv.textContent = 'Erreur réseau.';
alertDiv.textContent = window.gettext ? window.gettext('Erreur réseau.') : 'Erreur réseau.';
alertDiv.classList.remove('d-none');
})
.finally(() => {

View file

@ -133,3 +133,11 @@ msgstr "@"
#: loko/common/static/common/jquery-ui.min.js:6
msgid "!"
msgstr "!"
#: loko/common/static/common/address_search_control.js:148
msgid "Rechercher une adresse…"
msgstr "Search an address…"
msgid "Rechercher une adresse..."
msgstr "Search an address..."

View file

@ -133,3 +133,11 @@ msgstr "@"
#: loko/common/static/common/jquery-ui.min.js:6
msgid "!"
msgstr "!"
#: loko/common/static/common/address_search_control.js:148
msgid "Rechercher une adresse…"
msgstr "Rechercher une adresse…"
msgid "Rechercher une adresse..."
msgstr "Rechercher une adresse..."

View file

@ -135,3 +135,11 @@ msgstr "@"
#: loko/common/static/common/jquery-ui.min.js:6
msgid "!"
msgstr "!"
#: loko/common/static/common/address_search_control.js:148
msgid "Rechercher une adresse…"
msgstr "Zoek een adres…"
msgid "Rechercher une adresse..."
msgstr "Zoek een adres..."

View file

@ -144,8 +144,9 @@
*/
constructor(opts = {}) {
super();
const defaultPlaceholder = (typeof gettext !== 'undefined' ? gettext('Rechercher une adresse…') : 'Rechercher une adresse…');
this._opts = Object.assign({
placeholder : 'Rechercher une adresse…',
placeholder : defaultPlaceholder,
minChars : 2,
debounce : 250,
markerColor : '#0d6efd',

View file

@ -2027,3 +2027,70 @@ msgstr "Team"
#~ msgid "Présence de sédiments dans le bassin d'orage ?"
#~ msgstr "Presence of sediment in stormwater basin?"
#: inspections/templates/inspections/quick_inspection_map.html:505
msgid "Position actualisée"
msgstr "Position updated"
#: inspections/templates/inspections/quick_inspection_map.html:506
msgid "Géolocalisation..."
msgstr "Geolocation..."
#: inspections/templates/inspections/quick_inspection_map.html:507
msgid "GPS indisponible"
msgstr "GPS unavailable"
#: inspections/templates/inspections/quick_inspection_map.html:508
msgid "Rechercher une adresse…"
msgstr "Search an address…"
#: inspections/templates/inspections/quick_inspection_map.html:510
msgid "Inspections (Désactivé)"
msgstr "Inspections (Disabled)"
#: inspections/templates/inspections/quick_inspection_map.html:511
msgid "Inspections (1 mois)"
msgstr "Inspections (1 month)"
#: inspections/templates/inspections/quick_inspection_map.html:513
msgid "Inspections (6 mois)"
msgstr "Inspections (6 months)"
#: inspections/templates/inspections/quick_inspection_map.html:514
msgid "Inspections (1 an)"
msgstr "Inspections (1 year)"
#: inspections/templates/inspections/quick_inspection_map.html:515
msgid "Inspections (Tout)"
msgstr "Inspections (All)"
msgid "Plein écran"
msgstr "Full screen"
msgid "Photo"
msgstr "Photo"
msgid "Détail"
msgstr "Detail"
msgid "Voir l'inspection"
msgstr "View inspection"
msgid "Équipement"
msgstr "Equipment"
msgid "inspections"
msgstr "inspections"
msgid "Aperçu mât"
msgstr "Pole preview"
msgid "Panneau"
msgstr "Sign"
msgid "Précédent"
msgstr "Previous"
msgid "Suivant"
msgstr "Next"

View file

@ -2040,3 +2040,70 @@ msgstr "Équipe"
#~ msgid "Présence de sédiments dans le bassin d'orage ?"
#~ msgstr "Présence de sédiments dans le bassin d'orage ?"
#: inspections/templates/inspections/quick_inspection_map.html:505
msgid "Position actualisée"
msgstr "Position actualisée"
#: inspections/templates/inspections/quick_inspection_map.html:506
msgid "Géolocalisation..."
msgstr "Géolocalisation..."
#: inspections/templates/inspections/quick_inspection_map.html:507
msgid "GPS indisponible"
msgstr "GPS indisponible"
#: inspections/templates/inspections/quick_inspection_map.html:508
msgid "Rechercher une adresse…"
msgstr "Rechercher une adresse…"
#: inspections/templates/inspections/quick_inspection_map.html:510
msgid "Inspections (Désactivé)"
msgstr "Inspections (Désactivé)"
#: inspections/templates/inspections/quick_inspection_map.html:511
msgid "Inspections (1 mois)"
msgstr "Inspections (1 mois)"
#: inspections/templates/inspections/quick_inspection_map.html:513
msgid "Inspections (6 mois)"
msgstr "Inspections (6 mois)"
#: inspections/templates/inspections/quick_inspection_map.html:514
msgid "Inspections (1 an)"
msgstr "Inspections (1 an)"
#: inspections/templates/inspections/quick_inspection_map.html:515
msgid "Inspections (Tout)"
msgstr "Inspections (Tout)"
msgid "Plein écran"
msgstr "Plein écran"
msgid "Photo"
msgstr "Photo"
msgid "Détail"
msgstr "Détail"
msgid "Voir l'inspection"
msgstr "Voir l'inspection"
msgid "Équipement"
msgstr "Équipement"
msgid "inspections"
msgstr "inspections"
msgid "Aperçu mât"
msgstr "Aperçu mât"
msgid "Panneau"
msgstr "Panneau"
msgid "Précédent"
msgstr "Précédent"
msgid "Suivant"
msgstr "Suivant"

View file

@ -2028,3 +2028,70 @@ msgstr "Team"
#~ msgid "Présence de sédiments dans le bassin d'orage ?"
#~ msgstr "Aanwezigheid van sediment in het stormbekken?"
#: inspections/templates/inspections/quick_inspection_map.html:505
msgid "Position actualisée"
msgstr "Positie bijgewerkt"
#: inspections/templates/inspections/quick_inspection_map.html:506
msgid "Géolocalisation..."
msgstr "Geolocatie..."
#: inspections/templates/inspections/quick_inspection_map.html:507
msgid "GPS indisponible"
msgstr "GPS niet beschikbaar"
#: inspections/templates/inspections/quick_inspection_map.html:508
msgid "Rechercher une adresse…"
msgstr "Zoek een adres…"
#: inspections/templates/inspections/quick_inspection_map.html:510
msgid "Inspections (Désactivé)"
msgstr "Inspecties (Uitgeschakeld)"
#: inspections/templates/inspections/quick_inspection_map.html:511
msgid "Inspections (1 mois)"
msgstr "Inspecties (1 maand)"
#: inspections/templates/inspections/quick_inspection_map.html:513
msgid "Inspections (6 mois)"
msgstr "Inspecties (6 maanden)"
#: inspections/templates/inspections/quick_inspection_map.html:514
msgid "Inspections (1 an)"
msgstr "Inspecties (1 jaar)"
#: inspections/templates/inspections/quick_inspection_map.html:515
msgid "Inspections (Tout)"
msgstr "Inspecties (Alles)"
msgid "Plein écran"
msgstr "Volledig scherm"
msgid "Photo"
msgstr "Foto"
msgid "Détail"
msgstr "Detail"
msgid "Voir l'inspection"
msgstr "Inspectie bekijken"
msgid "Équipement"
msgstr "Uitrusting"
msgid "inspections"
msgstr "inspecties"
msgid "Aperçu mât"
msgstr "Overzicht paal"
msgid "Panneau"
msgstr "Bord"
msgid "Précédent"
msgstr "Vorige"
msgid "Suivant"
msgstr "Volgende"

View file

@ -11,7 +11,7 @@
<div class="d-flex align-items-center gap-3 p-2 bg-white rounded-3 border mb-3">
<div style="width: 52px; height: 52px; display: flex; align-items: center; justify-content: center; background: #f8f9fa; border-radius: 8px; border: 1px solid #e9ecef;">
<img src="/static/assets/road_signs/2025/{% if leaf.verified_signpanel_type %}{{ leaf.verified_signpanel_type.code|upper }}{% elif insp.asset.signpanel_type %}{{ insp.asset.signpanel_type.code|upper }}{% else %}C1{% endif %}.svg"
alt="{% if leaf.verified_signpanel_type %}{{ leaf.verified_signpanel_type.code }}{% elif insp.asset.signpanel_type %}{{ insp.asset.signpanel_type.code }}{% else %}Panneau{% endif %}"
alt="{% if leaf.verified_signpanel_type %}{{ leaf.verified_signpanel_type.code }}{% elif insp.asset.signpanel_type %}{{ insp.asset.signpanel_type.code }}{% else %}{% translate 'Panneau' %}{% endif %}"
style="max-width: 44px; max-height: 44px; object-fit: contain;"
onerror="this.onerror=null; this.src='/static/assets/road_signs/2025/' + (this.alt || 'default') + '.png';">
</div>

View file

@ -8,7 +8,7 @@
{% translate "Contrôle de signalisation routière" %}
</span>
<span class="badge bg-light text-dark border">
{% if asset.code %}{{ asset.code }}{% elif asset.signpanel_type %}{{ asset.signpanel_type.code }}{% else %}Panneau{% endif %}
{% if asset.code %}{{ asset.code }}{% elif asset.signpanel_type %}{{ asset.signpanel_type.code }}{% else %}{% translate "Panneau" %}{% endif %}
</span>
</div>
@ -151,7 +151,7 @@
<div style="width: 48px; height: 48px; display: flex; align-items: center; justify-content: center; background: white; border-radius: 8px; border: 1px solid #dee2e6;">
<img id="sign_preview_img"
src="{% if asset.signpanel_type and asset.signpanel_type.code %}/static/assets/road_signs/2025/{{ asset.signpanel_type.code|upper }}.svg{% else %}/static/assets/road_signs/2025/C1.svg{% endif %}"
alt="Panneau"
alt="{% translate 'Panneau' %}"
style="max-width: 42px; max-height: 42px; object-fit: contain;"
onerror="this.onerror=null; this.src='/static/assets/road_signs/2025/' + (this.alt || 'default') + '.png';">
</div>

View file

@ -81,7 +81,7 @@
<!-- Aperçu de la photo prise -->
<div id="new_sign_photo_preview_box" class="mt-2 d-none">
<img id="new_sign_photo_preview" src="" alt="Aperçu mât" class="img-fluid rounded border shadow-sm" style="max-height: 180px; object-fit: contain;">
<img id="new_sign_photo_preview" src="" alt="{% translate 'Aperçu mât' %}" class="img-fluid rounded border shadow-sm" style="max-height: 180px; object-fit: contain;">
</div>
</div>

View file

@ -179,7 +179,7 @@
<h5 class="modal-title fw-bold" id="inspectionDetailModalLabel{{ insp.id }}">
<i class="bi {{ insp.thematic_icon }} me-2 text-primary"></i>{% translate "Détail de l'inspection" %}
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% translate 'Fermer' %}"></button>
</div>
<div class="modal-body p-3">
{% if insp.is_cancelled %}
@ -299,7 +299,7 @@
<div class="carousel-item {% if forloop.first %}active{% endif %} h-100">
<div class="d-flex align-items-center justify-content-center bg-black position-relative" style="height: 260px;">
<img data-src="{{ doc.file_url }}" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1 1'%3E%3C/svg%3E" loading="lazy" class="d-block img-fluid mh-100 mw-100 list-insp-carousel-trigger" style="object-fit: contain; max-height: 260px; cursor: pointer;" data-insp-id="{{ insp.id }}" data-img-index="{{ forloop.counter0 }}" alt="{{ doc.filename }}">
<button type="button" class="btn btn-sm btn-dark bg-opacity-75 text-white rounded-circle p-1.5 shadow list-insp-carousel-trigger position-absolute bottom-0 end-0 m-2" style="z-index: 10; cursor: pointer;" data-insp-id="{{ insp.id }}" data-img-index="{{ forloop.counter0 }}" title="Plein écran">
<button type="button" class="btn btn-sm btn-dark bg-opacity-75 text-white rounded-circle p-1.5 shadow list-insp-carousel-trigger position-absolute bottom-0 end-0 m-2" style="z-index: 10; cursor: pointer;" data-insp-id="{{ insp.id }}" data-img-index="{{ forloop.counter0 }}" title="{% translate 'Plein écran' %}">
<i class="bi bi-arrows-fullscreen"></i>
</button>
</div>
@ -309,11 +309,11 @@
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselInsp{{ insp.id }}" data-bs-slide="prev">
<span class="carousel-control-prev-icon p-2 rounded-circle bg-dark bg-opacity-50" aria-hidden="true"></span>
<span class="visually-hidden">Précédent</span>
<span class="visually-hidden">{% translate "Précédent" %}</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselInsp{{ insp.id }}" data-bs-slide="next">
<span class="carousel-control-next-icon p-2 rounded-circle bg-dark bg-opacity-50" aria-hidden="true"></span>
<span class="visually-hidden">Suivant</span>
<span class="visually-hidden">{% translate "Suivant" %}</span>
</button>
</div>
@ -368,7 +368,7 @@
<!-- Overlay Carrousel Plein Écran pour Photos (avec bouton fermer) -->
<div id="fullscreenPhotoOverlay" class="d-none position-fixed top-0 start-0 w-100 h-100 bg-black" style="z-index: 999999;">
<!-- Bouton Fermer -->
<button type="button" class="btn-close btn-close-white position-absolute top-0 end-0 m-3 fs-4 shadow p-2" id="btn-close-photo-overlay" style="z-index: 1000005; cursor: pointer;" aria-label="Fermer"></button>
<button type="button" class="btn-close btn-close-white position-absolute top-0 end-0 m-3 fs-4 shadow p-2" id="btn-close-photo-overlay" style="z-index: 1000005; cursor: pointer;" aria-label="{% translate 'Fermer' %}"></button>
<!-- Conteneur Carrousel -->
<div id="fullscreenPhotoCarousel" class="carousel slide w-100 h-100" data-bs-ride="false">
@ -376,11 +376,11 @@
<div class="carousel-inner w-100 h-100" id="fullscreen-carousel-inner"></div>
<button class="carousel-control-prev" type="button" data-bs-target="#fullscreenPhotoCarousel" data-bs-slide="prev" style="z-index: 1000000;">
<span class="carousel-control-prev-icon p-3 rounded-circle bg-dark bg-opacity-75" aria-hidden="true"></span>
<span class="visually-hidden">Précédent</span>
<span class="visually-hidden">{% translate "Précédent" %}</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#fullscreenPhotoCarousel" data-bs-slide="next" style="z-index: 1000000;">
<span class="carousel-control-next-icon p-3 rounded-circle bg-dark bg-opacity-75" aria-hidden="true"></span>
<span class="visually-hidden">Suivant</span>
<span class="visually-hidden">{% translate "Suivant" %}</span>
</button>
</div>
</div>
@ -401,7 +401,7 @@ document.addEventListener('DOMContentLoaded', function() {
imgs.forEach(img => {
imagesData.push({
url: img.getAttribute('src'),
filename: img.getAttribute('alt') || 'Photo'
filename: img.getAttribute('alt') || '{% translate "Photo" %}'
});
});
@ -434,7 +434,7 @@ document.addEventListener('DOMContentLoaded', function() {
ind.className = 'active';
ind.setAttribute('aria-current', 'true');
}
ind.setAttribute('aria-label', `Photo ${idx + 1}`);
ind.setAttribute('aria-label', `{% translate "Photo" %} ${idx + 1}`);
fsIndicators.appendChild(ind);
}
});
@ -481,7 +481,7 @@ document.addEventListener('DOMContentLoaded', function() {
<i class="bi bi-map text-info fs-5"></i>
{% translate "Carte des résultats d'inspections" %}
</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="{% translate 'Fermer' %}"></button>
</div>
<div class="modal-body p-0 position-relative">
<div id="inspections-list-modal-map" style="width: 100%; height: 75vh; border-radius: 0 0 0.5rem 0.5rem;"></div>
@ -641,7 +641,7 @@ document.addEventListener('DOMContentLoaded', function() {
<div class="small text-muted mb-1"><i class="bi bi-person me-1"></i>${insp.inspector}</div>
<p class="small text-secondary mb-2">${insp.summary}</p>
<button type="button" class="btn btn-xs btn-outline-primary w-100 py-1 open-detail-from-modal" data-insp-id="${insp.id}">
<i class="bi bi-eye me-1"></i>Détail
<i class="bi bi-eye me-1"></i>{% translate "Détail" %}
</button>
</div>
`;
@ -659,8 +659,8 @@ document.addEventListener('DOMContentLoaded', function() {
</div>
<div class="small text-muted text-truncate" style="max-width: 220px;"><i class="bi bi-person me-1"></i>${insp.inspector}</div>
</div>
<button type="button" class="btn btn-sm btn-outline-primary px-2 py-1 flex-shrink-0 open-detail-from-modal ms-1" data-insp-id="${insp.id}" style="font-size: 0.75rem; border-radius: 0.375rem;" title="Voir l'inspection">
<i class="bi bi-eye me-1"></i>Détail
<button type="button" class="btn btn-sm btn-outline-primary px-2 py-1 flex-shrink-0 open-detail-from-modal ms-1" data-insp-id="${insp.id}" style="font-size: 0.75rem; border-radius: 0.375rem;" title="{% translate "Voir l'inspection" %}">
<i class="bi bi-eye me-1"></i>{% translate "Détail" %}
</button>
</div>
`;
@ -669,8 +669,8 @@ document.addEventListener('DOMContentLoaded', function() {
contentHtml = `
<div class="p-1" style="min-width: 320px; max-width: 360px;">
<div class="d-flex justify-content-between align-items-center mb-2 pb-1 border-bottom">
<h6 class="fw-bold mb-0 text-dark text-truncate" style="max-width: 230px;">${popupTitle || 'Équipement'}</h6>
<span class="badge bg-secondary rounded-pill small">${sortedInspections.length} inspections</span>
<h6 class="fw-bold mb-0 text-dark text-truncate" style="max-width: 230px;">${popupTitle || '{% translate "Équipement" %}'}</h6>
<span class="badge bg-secondary rounded-pill small">${sortedInspections.length} {% translate "inspections" %}</span>
</div>
<div class="overflow-auto" style="max-height: 240px;">
${rowsHtml}

View file

@ -90,7 +90,7 @@
<select name="zone" class="form-select form-select-sm" onchange="this.form.submit()">
<option value="">{% translate "-- Districts / Zones --" %}</option>
{% for z in zones %}
<option value="{{ z.id }}" {% if selected_zone == z.id|stringformat:"s" %}selected{% endif %}>{{ z.name_fr }}</option>
<option value="{{ z.id }}" {% if selected_zone == z.id|stringformat:"s" %}selected{% endif %}>{{ z.name }}</option>
{% endfor %}
</select>
</div>
@ -242,7 +242,7 @@
<h5 class="modal-title fw-bold" id="inspectionDetailModalLabel{{ insp.id }}">
<i class="bi {{ insp.thematic_icon }} me-2 text-primary"></i>{% translate "Détail de l'inspection" %}
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% translate 'Fermer' %}"></button>
</div>
<div class="modal-body p-3">
{% if insp.is_cancelled %}
@ -385,7 +385,7 @@
<div class="carousel-item {% if forloop.first %}active{% endif %} h-100">
<div class="d-flex align-items-center justify-content-center bg-black position-relative" style="height: 260px;">
<img data-src="{{ doc.file_url }}" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1 1'%3E%3C/svg%3E" loading="lazy" class="d-block img-fluid mh-100 mw-100 list-insp-carousel-trigger" style="object-fit: contain; max-height: 260px; cursor: pointer;" data-insp-id="{{ insp.id }}" data-img-index="{{ forloop.counter0 }}" alt="{{ doc.filename }}">
<button type="button" class="btn btn-sm btn-dark bg-opacity-75 text-white rounded-circle p-1.5 shadow list-insp-carousel-trigger position-absolute bottom-0 end-0 m-2" style="z-index: 10; cursor: pointer;" data-insp-id="{{ insp.id }}" data-img-index="{{ forloop.counter0 }}" title="Plein écran">
<button type="button" class="btn btn-sm btn-dark bg-opacity-75 text-white rounded-circle p-1.5 shadow list-insp-carousel-trigger position-absolute bottom-0 end-0 m-2" style="z-index: 10; cursor: pointer;" data-insp-id="{{ insp.id }}" data-img-index="{{ forloop.counter0 }}" title="{% translate 'Plein écran' %}">
<i class="bi bi-arrows-fullscreen"></i>
</button>
</div>
@ -395,11 +395,11 @@
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselInsp{{ insp.id }}" data-bs-slide="prev">
<span class="carousel-control-prev-icon p-2 rounded-circle bg-dark bg-opacity-50" aria-hidden="true"></span>
<span class="visually-hidden">Précédent</span>
<span class="visually-hidden">{% translate "Précédent" %}</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselInsp{{ insp.id }}" data-bs-slide="next">
<span class="carousel-control-next-icon p-2 rounded-circle bg-dark bg-opacity-50" aria-hidden="true"></span>
<span class="visually-hidden">Suivant</span>
<span class="visually-hidden">{% translate "Suivant" %}</span>
</button>
</div>
@ -461,7 +461,7 @@
<!-- Overlay Carrousel Plein Écran pour Photos (avec bouton fermer) -->
<div id="fullscreenPhotoOverlay" class="d-none position-fixed top-0 start-0 w-100 h-100 bg-black" style="z-index: 999999;">
<!-- Bouton Fermer -->
<button type="button" class="btn-close btn-close-white position-absolute top-0 end-0 m-3 fs-4 shadow p-2" id="btn-close-photo-overlay" style="z-index: 1000005; cursor: pointer;" aria-label="Fermer"></button>
<button type="button" class="btn-close btn-close-white position-absolute top-0 end-0 m-3 fs-4 shadow p-2" id="btn-close-photo-overlay" style="z-index: 1000005; cursor: pointer;" aria-label="{% translate 'Fermer' %}"></button>
<!-- Conteneur Carrousel -->
<div id="fullscreenPhotoCarousel" class="carousel slide w-100 h-100" data-bs-ride="false">
@ -469,11 +469,11 @@
<div class="carousel-inner w-100 h-100" id="fullscreen-carousel-inner"></div>
<button class="carousel-control-prev" type="button" data-bs-target="#fullscreenPhotoCarousel" data-bs-slide="prev" style="z-index: 1000000;">
<span class="carousel-control-prev-icon p-3 rounded-circle bg-dark bg-opacity-75" aria-hidden="true"></span>
<span class="visually-hidden">Précédent</span>
<span class="visually-hidden">{% translate "Précédent" %}</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#fullscreenPhotoCarousel" data-bs-slide="next" style="z-index: 1000000;">
<span class="carousel-control-next-icon p-3 rounded-circle bg-dark bg-opacity-75" aria-hidden="true"></span>
<span class="visually-hidden">Suivant</span>
<span class="visually-hidden">{% translate "Suivant" %}</span>
</button>
</div>
</div>
@ -494,7 +494,7 @@ document.addEventListener('DOMContentLoaded', function() {
imgs.forEach(img => {
imagesData.push({
url: img.getAttribute('src'),
filename: img.getAttribute('alt') || 'Photo'
filename: img.getAttribute('alt') || '{% translate "Photo" %}'
});
});
@ -527,7 +527,7 @@ document.addEventListener('DOMContentLoaded', function() {
ind.className = 'active';
ind.setAttribute('aria-current', 'true');
}
ind.setAttribute('aria-label', `Photo ${idx + 1}`);
ind.setAttribute('aria-label', `{% translate "Photo" %} ${idx + 1}`);
fsIndicators.appendChild(ind);
}
});
@ -564,7 +564,7 @@ document.addEventListener('DOMContentLoaded', function() {
<i class="bi bi-map text-info fs-5"></i>
{% translate "Carte des résultats d'inspections" %}
</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="{% translate 'Fermer' %}"></button>
</div>
<div class="modal-body p-0 position-relative">
<div id="inspections-list-modal-map" style="width: 100%; height: 75vh; border-radius: 0 0 0.5rem 0.5rem;"></div>
@ -724,7 +724,7 @@ document.addEventListener('DOMContentLoaded', function() {
<div class="small text-muted mb-1"><i class="bi bi-person me-1"></i>${insp.inspector}</div>
<p class="small text-secondary mb-2">${insp.summary}</p>
<button type="button" class="btn btn-xs btn-outline-primary w-100 py-1 open-detail-from-modal" data-insp-id="${insp.id}">
<i class="bi bi-eye me-1"></i>Détail
<i class="bi bi-eye me-1"></i>{% translate "Détail" %}
</button>
</div>
`;
@ -742,8 +742,8 @@ document.addEventListener('DOMContentLoaded', function() {
</div>
<div class="small text-muted text-truncate" style="max-width: 220px;"><i class="bi bi-person me-1"></i>${insp.inspector}</div>
</div>
<button type="button" class="btn btn-sm btn-outline-primary px-2 py-1 flex-shrink-0 open-detail-from-modal ms-1" data-insp-id="${insp.id}" style="font-size: 0.75rem; border-radius: 0.375rem;" title="Voir l'inspection">
<i class="bi bi-eye me-1"></i>Détail
<button type="button" class="btn btn-sm btn-outline-primary px-2 py-1 flex-shrink-0 open-detail-from-modal ms-1" data-insp-id="${insp.id}" style="font-size: 0.75rem; border-radius: 0.375rem;" title="{% translate "Voir l'inspection" %}">
<i class="bi bi-eye me-1"></i>{% translate "Détail" %}
</button>
</div>
`;
@ -752,8 +752,8 @@ document.addEventListener('DOMContentLoaded', function() {
contentHtml = `
<div class="p-1" style="min-width: 320px; max-width: 360px;">
<div class="d-flex justify-content-between align-items-center mb-2 pb-1 border-bottom">
<h6 class="fw-bold mb-0 text-dark text-truncate" style="max-width: 230px;">${popupTitle || 'Équipement'}</h6>
<span class="badge bg-secondary rounded-pill small">${sortedInspections.length} inspections</span>
<h6 class="fw-bold mb-0 text-dark text-truncate" style="max-width: 230px;">${popupTitle || '{% translate "Équipement" %}'}</h6>
<span class="badge bg-secondary rounded-pill small">${sortedInspections.length} {% translate "inspections" %}</span>
</div>
<div class="overflow-auto" style="max-height: 240px;">
${rowsHtml}

View file

@ -227,7 +227,7 @@
<div id="map-warning-alert" class="alert alert-warning alert-dismissible fade show d-none shadow-sm py-2 px-3 mt-2 mb-0 small" role="alert">
<i class="bi bi-exclamation-triangle-fill me-1 text-warning"></i>
<span id="map-warning-text">{% translate "Veuillez zoomer sur la carte pour afficher les équipements." %}</span>
<button type="button" class="btn-close py-2" data-bs-dismiss="alert" aria-label="Close"></button>
<button type="button" class="btn-close py-2" data-bs-dismiss="alert" aria-label="{% translate 'Fermer' %}"></button>
</div>
</div>
@ -277,7 +277,7 @@
<h6 class="modal-title fw-bold" id="thematicChooserModalLabel">
<i class="bi bi-layers-fill text-primary me-1"></i>{% translate "Choisir une thématique" %}
</h6>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% translate 'Fermer' %}"></button>
</div>
<div class="modal-body p-3">
<div class="row g-2" id="thematic-tiles-container">
@ -309,7 +309,7 @@
<h6 class="modal-title fw-bold" id="categoryChooserModalLabel">
<i class="bi bi-tags-fill text-primary me-1"></i>{% translate "Filtrer par catégorie" %}
</h6>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% translate 'Fermer' %}"></button>
</div>
<div class="modal-body p-3">
<div class="list-group list-group-flush" id="category-list-container">
@ -337,7 +337,7 @@
<h6 class="modal-title fw-bold" id="inspectionsHistoryModalLabel">
<i class="bi bi-clock-history text-primary me-1"></i>{% translate "Historique des inspections sur la carte" %}
</h6>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% translate 'Fermer' %}"></button>
</div>
<div class="modal-body p-3">
<p class="text-muted small mb-3">
@ -386,7 +386,7 @@
<button type="button" class="btn btn-outline-primary btn-sm fw-semibold d-none" id="map-insp-edit-btn" onclick="openEditInspectionFromMap()">
<i class="bi bi-pencil-square me-1"></i>{% translate "Modifier" %}
</button>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% translate 'Fermer' %}"></button>
</div>
</div>
<div class="modal-body p-3">
@ -437,11 +437,11 @@
<div class="carousel-inner" id="map-insp-carousel-inner"></div>
<button class="carousel-control-prev" type="button" data-bs-target="#mapInspectionPhotosCarousel" data-bs-slide="prev">
<span class="carousel-control-prev-icon p-2 rounded-circle bg-dark bg-opacity-50" aria-hidden="true"></span>
<span class="visually-hidden">Précédent</span>
<span class="visually-hidden">{% translate "Précédent" %}</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#mapInspectionPhotosCarousel" data-bs-slide="next">
<span class="carousel-control-next-icon p-2 rounded-circle bg-dark bg-opacity-50" aria-hidden="true"></span>
<span class="visually-hidden">Suivant</span>
<span class="visually-hidden">{% translate "Suivant" %}</span>
</button>
</div>
</div>
@ -461,7 +461,7 @@
<!-- Overlay Carrousel Plein Écran pour Photos (avec bouton fermer) -->
<div id="fullscreenPhotoOverlay" class="d-none position-fixed top-0 start-0 w-100 h-100 bg-black" style="z-index: 999999;">
<!-- Bouton Fermer -->
<button type="button" class="btn-close btn-close-white position-absolute top-0 end-0 m-3 fs-4 shadow p-2" id="btn-close-photo-overlay" style="z-index: 1000005; cursor: pointer;" aria-label="Fermer"></button>
<button type="button" class="btn-close btn-close-white position-absolute top-0 end-0 m-3 fs-4 shadow p-2" id="btn-close-photo-overlay" style="z-index: 1000005; cursor: pointer;" aria-label="{% translate 'Fermer' %}"></button>
<!-- Conteneur Carrousel -->
<div id="fullscreenPhotoCarousel" class="carousel slide w-100 h-100" data-bs-ride="false">
@ -469,11 +469,11 @@
<div class="carousel-inner w-100 h-100" id="fullscreen-carousel-inner"></div>
<button class="carousel-control-prev" type="button" data-bs-target="#fullscreenPhotoCarousel" data-bs-slide="prev" style="z-index: 1000000;">
<span class="carousel-control-prev-icon p-3 rounded-circle bg-dark bg-opacity-75" aria-hidden="true"></span>
<span class="visually-hidden">Précédent</span>
<span class="visually-hidden">{% translate "Précédent" %}</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#fullscreenPhotoCarousel" data-bs-slide="next" style="z-index: 1000000;">
<span class="carousel-control-next-icon p-3 rounded-circle bg-dark bg-opacity-75" aria-hidden="true"></span>
<span class="visually-hidden">Suivant</span>
<span class="visually-hidden">{% translate "Suivant" %}</span>
</button>
</div>
</div>
@ -501,6 +501,20 @@
window.PRESELECT_LAT = {{ preselect_lat|safe }};
window.PRESELECT_THEMATIC_CODE = {{ preselect_thematic_code|safe }};
window.PRESELECT_CATEGORY_ID = {{ preselect_category_id|safe }};
window.INSPECTION_MAP_I18N = {
positionUpdated: "{% translate 'Position actualisée' %}",
geolocation: "{% translate 'Géolocalisation...' %}",
gpsUnavailable: "{% translate 'GPS indisponible' %}",
searchAddress: "{% translate 'Rechercher une adresse…' %}",
periodLabels: {
'disabled': "{% translate 'Inspections (Désactivé)' %}",
'1m': "{% translate 'Inspections (1 mois)' %}",
'3m': "{% translate 'Inspections (3 mois)' %}",
'6m': "{% translate 'Inspections (6 mois)' %}",
'1y': "{% translate 'Inspections (1 an)' %}",
'all': "{% translate 'Inspections (Tout)' %}"
}
};
</script>
<script src="{% static 'assets/inspection_map.js' %}"></script>
{% endblock %}