192 lines
7.6 KiB
JavaScript
192 lines
7.6 KiB
JavaScript
/**
|
|
* Asset Location Edit - JavaScript handler
|
|
* Handles the changing of asset location in edit mode
|
|
*/
|
|
(function() {
|
|
'use strict';
|
|
|
|
const changeLocationBtn = document.getElementById('changeLocationBtn');
|
|
const changeLocationSelect = document.getElementById('changeLocationSelect');
|
|
const changeLocationSearch = document.getElementById('changeLocationSearch');
|
|
const changeLocationSearchHelp = document.getElementById('changeLocationSearchHelp');
|
|
const confirmChangeLocationBtn = document.getElementById('confirmChangeLocationBtn');
|
|
const changeLocationAlert = document.getElementById('changeLocationAlert');
|
|
let searchDebounceTimer = null;
|
|
|
|
if (!changeLocationBtn) return; // Skip if location editing not available
|
|
|
|
// Initialize location selection when modal is shown
|
|
const changeLocationModal = document.getElementById('changeLocationModal');
|
|
if (changeLocationModal) {
|
|
changeLocationModal.addEventListener('show.bs.modal', function() {
|
|
if (changeLocationSearch) changeLocationSearch.value = '';
|
|
setSearchHelp('');
|
|
loadLocationsForAsset('');
|
|
});
|
|
}
|
|
|
|
if (changeLocationSearch) {
|
|
changeLocationSearch.addEventListener('input', function() {
|
|
const query = this.value.trim();
|
|
clearTimeout(searchDebounceTimer);
|
|
|
|
searchDebounceTimer = setTimeout(() => {
|
|
if (query.length === 0 || query.length >= 2) {
|
|
loadLocationsForAsset(query);
|
|
} else {
|
|
setSearchHelp(gettext('Saisissez au moins 2 caractères pour rechercher.'));
|
|
}
|
|
}, 250);
|
|
});
|
|
}
|
|
|
|
// Handle location change confirmation
|
|
if (confirmChangeLocationBtn) {
|
|
confirmChangeLocationBtn.addEventListener('click', function() {
|
|
handleLocationChange();
|
|
});
|
|
}
|
|
|
|
function loadLocationsForAsset(query) {
|
|
const assetId = changeLocationSelect.dataset.assetId;
|
|
const thematicCode = changeLocationSelect.dataset.thematic;
|
|
|
|
if (!assetId || !thematicCode) {
|
|
console.error('Missing asset ID or thematic code');
|
|
return;
|
|
}
|
|
|
|
changeLocationSelect.innerHTML = '<option value="">' + gettext('Chargement...') + '</option>';
|
|
changeLocationSelect.disabled = true;
|
|
|
|
// Fetch available locations based on thematic
|
|
const params = new URLSearchParams();
|
|
params.set('limit', '120');
|
|
if (query) params.set('q', query);
|
|
const url = `/assets/${thematicCode}/asset/${assetId}/available-locations/?${params.toString()}`;
|
|
|
|
fetch(url)
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
throw new Error('Network response was not ok');
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
changeLocationSelect.innerHTML = '<option value="">' + gettext('Sélectionner une localisation...') + '</option>';
|
|
|
|
if (data.locations && data.locations.length > 0) {
|
|
data.locations.forEach(location => {
|
|
const option = document.createElement('option');
|
|
option.value = location.id;
|
|
option.textContent = `${location.code} - ${location.name}`;
|
|
changeLocationSelect.appendChild(option);
|
|
});
|
|
changeLocationSelect.disabled = false;
|
|
if (data.has_more) {
|
|
setSearchHelp(gettext('Résultats limités. Affinez la recherche pour trouver plus facilement.'));
|
|
} else {
|
|
setSearchHelp('');
|
|
}
|
|
} else {
|
|
changeLocationSelect.innerHTML = '<option value="">' + gettext('Aucune localisation disponible') + '</option>';
|
|
if (query) {
|
|
setSearchHelp(gettext('Aucun résultat pour cette recherche.'));
|
|
} else {
|
|
setSearchHelp('');
|
|
}
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error loading locations:', error);
|
|
changeLocationSelect.innerHTML = '<option value="">' + gettext('Erreur de chargement') + '</option>';
|
|
setSearchHelp('');
|
|
showAlert('danger', gettext('Erreur lors du chargement des localisations'));
|
|
});
|
|
}
|
|
|
|
function setSearchHelp(message) {
|
|
if (!changeLocationSearchHelp) return;
|
|
changeLocationSearchHelp.textContent = message || '';
|
|
}
|
|
|
|
function handleLocationChange() {
|
|
const locationId = changeLocationSelect.value;
|
|
|
|
if (!locationId) {
|
|
showAlert('warning', gettext('Veuillez sélectionner une localisation'));
|
|
return;
|
|
}
|
|
|
|
// Disable button
|
|
confirmChangeLocationBtn.disabled = true;
|
|
const originalText = confirmChangeLocationBtn.innerHTML;
|
|
confirmChangeLocationBtn.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span>' + gettext('Mise à jour...');
|
|
|
|
// Get asset info from page
|
|
const assetContainer = document.getElementById('asset-detail-container');
|
|
const assetModel = assetContainer.dataset.assetModel;
|
|
const assetId = assetContainer.dataset.assetId;
|
|
|
|
// Send update request
|
|
fetch(`/assets/${assetModel}/${assetId}/update/`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-CSRFToken': getCookie('csrftoken')
|
|
},
|
|
body: JSON.stringify({
|
|
location_id: locationId,
|
|
intersection_id: locationId // For compatibility with different asset types
|
|
})
|
|
})
|
|
.then(response => response.json())
|
|
.then(result => {
|
|
confirmChangeLocationBtn.disabled = false;
|
|
confirmChangeLocationBtn.innerHTML = originalText;
|
|
|
|
if (result.success) {
|
|
showAlert('success', gettext('Localisation mise à jour'));
|
|
setTimeout(() => {
|
|
window.location.reload();
|
|
}, 1000);
|
|
} else {
|
|
showAlert('danger', result.error || gettext('Erreur lors de la mise à jour'));
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
confirmChangeLocationBtn.disabled = false;
|
|
confirmChangeLocationBtn.innerHTML = originalText;
|
|
showAlert('danger', gettext('Erreur lors de la mise à jour'));
|
|
});
|
|
}
|
|
|
|
function showAlert(type, message) {
|
|
if (!changeLocationAlert) return;
|
|
|
|
changeLocationAlert.className = `alert alert-${type}`;
|
|
changeLocationAlert.innerHTML = message;
|
|
changeLocationAlert.classList.remove('d-none');
|
|
|
|
// Auto-hide after 5 seconds
|
|
setTimeout(() => {
|
|
changeLocationAlert.classList.add('d-none');
|
|
}, 5000);
|
|
}
|
|
|
|
function getCookie(name) {
|
|
let cookieValue = null;
|
|
if (document.cookie && document.cookie !== '') {
|
|
const cookies = document.cookie.split(';');
|
|
for (let i = 0; i < cookies.length; i++) {
|
|
const cookie = cookies[i].trim();
|
|
if (cookie.substring(0, name.length + 1) === (name + '=')) {
|
|
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return cookieValue;
|
|
}
|
|
})();
|