feat: enhance mobile asset map UI with floating alerts and updated limit handling
This commit is contained in:
parent
4b1bc59f1e
commit
2ada4f88b7
3 changed files with 204 additions and 134 deletions
|
|
@ -141,6 +141,30 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Alerte flottante sur la carte */
|
||||||
|
.map-floating-alert {
|
||||||
|
position: absolute;
|
||||||
|
top: 0.65rem;
|
||||||
|
left: 0.65rem;
|
||||||
|
right: 0.65rem;
|
||||||
|
z-index: 25;
|
||||||
|
background-color: rgba(240, 249, 255, 0.96) !important;
|
||||||
|
backdrop-filter: blur(8px);
|
||||||
|
border: 1px solid #bae6fd !important;
|
||||||
|
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18) !important;
|
||||||
|
animation: slideDownFadeIn 0.25s ease-out;
|
||||||
|
}
|
||||||
|
@keyframes slideDownFadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-8px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Bouton flottant GPS */
|
/* Bouton flottant GPS */
|
||||||
.map-gps-btn {
|
.map-gps-btn {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
@ -410,23 +434,10 @@
|
||||||
<div id="filterLimitAlert" class="alert alert-warning py-1.5 px-2.5 mb-1.5 small d-flex align-items-center gap-2 rounded-3 d-none flex-shrink-0" role="alert">
|
<div id="filterLimitAlert" class="alert alert-warning py-1.5 px-2.5 mb-1.5 small d-flex align-items-center gap-2 rounded-3 d-none flex-shrink-0" role="alert">
|
||||||
<i class="bi bi-exclamation-triangle-fill fs-6 text-warning flex-shrink-0"></i>
|
<i class="bi bi-exclamation-triangle-fill fs-6 text-warning flex-shrink-0"></i>
|
||||||
<div class="flex-grow-1" style="line-height: 1.25;">
|
<div class="flex-grow-1" style="line-height: 1.25;">
|
||||||
<strong>{% translate "Limite atteinte" %}</strong> : {% translate "Plus de 500 assets correspondent. Veuillez zoomer sur la carte ou affiner vos critères de recherche." %}
|
<strong>{% translate "Limite atteinte" %}</strong> : <span id="filterLimitAlertText">{% translate "Plus de 500 assets correspondent. Veuillez zoomer sur la carte ou affiner vos critères de recherche pour les afficher." %}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Alerte Aucun résultat dans la zone visible (invitation retour vue initiale) -->
|
|
||||||
<div id="noResultsInZoneAlert" class="alert alert-info py-2 px-2.5 mb-1.5 small d-flex align-items-center gap-2 rounded-3 shadow-sm d-none flex-shrink-0" role="alert">
|
|
||||||
<i class="bi bi-info-circle-fill fs-5 text-primary flex-shrink-0"></i>
|
|
||||||
<div class="flex-grow-1" style="line-height: 1.3;">
|
|
||||||
<div class="fw-semibold text-dark">{% translate "Aucun résultat dans cette zone" %}</div>
|
|
||||||
<div class="text-secondary small">{% translate "Appuyez sur le bouton pour revenir à la vue initiale." %}</div>
|
|
||||||
</div>
|
|
||||||
<button type="button" id="btnResetToInitialView" class="btn btn-sm btn-primary rounded-3 text-nowrap py-1.5 px-2.5 d-flex align-items-center gap-1 shadow-sm flex-shrink-0">
|
|
||||||
<i class="bi bi-arrows-angle-expand"></i>
|
|
||||||
<span>{% translate "Vue initiale" %}</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Indicateur de résultats & compteur -->
|
<!-- Indicateur de résultats & compteur -->
|
||||||
<div class="d-flex justify-content-between align-items-center mb-1.5 px-1 text-secondary small flex-shrink-0">
|
<div class="d-flex justify-content-between align-items-center mb-1.5 px-1 text-secondary small flex-shrink-0">
|
||||||
<div class="d-flex align-items-center gap-1 flex-wrap">
|
<div class="d-flex align-items-center gap-1 flex-wrap">
|
||||||
|
|
@ -451,6 +462,20 @@
|
||||||
<div id="assets-map-wrapper">
|
<div id="assets-map-wrapper">
|
||||||
<div id="assets-map"></div>
|
<div id="assets-map"></div>
|
||||||
|
|
||||||
|
<!-- Alerte flottante : Aucun résultat dans la zone visible (invitation retour vue initiale) -->
|
||||||
|
<div id="noResultsInZoneAlert" class="map-floating-alert alert alert-info py-2 px-2.5 mb-0 small d-flex align-items-center gap-2 rounded-3 shadow d-none" role="alert">
|
||||||
|
<i class="bi bi-info-circle-fill fs-5 text-primary flex-shrink-0"></i>
|
||||||
|
<div class="flex-grow-1" style="line-height: 1.25; min-width: 0;">
|
||||||
|
<div class="fw-semibold text-dark text-truncate">{% translate "Aucun résultat dans cette zone" %}</div>
|
||||||
|
<div class="text-secondary small">{% translate "Appuyez sur le bouton pour revenir à la vue initiale." %}</div>
|
||||||
|
</div>
|
||||||
|
<button type="button" id="btnResetToInitialView" class="btn btn-sm btn-primary rounded-3 text-nowrap py-1 px-2.5 d-flex align-items-center gap-1 shadow-sm flex-shrink-0">
|
||||||
|
<i class="bi bi-arrows-angle-expand"></i>
|
||||||
|
<span class="small">{% translate "Vue initiale" %}</span>
|
||||||
|
</button>
|
||||||
|
<button type="button" id="btnCloseNoResultsAlert" class="btn-close ms-0.5 flex-shrink-0" style="font-size: 0.7rem;" aria-label="{% translate 'Fermer' %}"></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Invite sélection thématique sur la carte -->
|
<!-- Invite sélection thématique sur la carte -->
|
||||||
<div id="mapThematicPrompt" class="position-absolute top-50 start-50 translate-middle text-center p-3 bg-white bg-opacity-95 rounded-4 shadow-sm border {% if selected_thematic %}d-none{% endif %}" style="z-index: 8; max-width: 85%; pointer-events: none;">
|
<div id="mapThematicPrompt" class="position-absolute top-50 start-50 translate-middle text-center p-3 bg-white bg-opacity-95 rounded-4 shadow-sm border {% if selected_thematic %}d-none{% endif %}" style="z-index: 8; max-width: 85%; pointer-events: none;">
|
||||||
<div class="rounded-circle bg-primary-subtle text-primary d-inline-flex p-3 mb-2">
|
<div class="rounded-circle bg-primary-subtle text-primary d-inline-flex p-3 mb-2">
|
||||||
|
|
@ -488,9 +513,9 @@
|
||||||
|
|
||||||
<div id="emptyListMessage" class="text-center py-5 d-none">
|
<div id="emptyListMessage" class="text-center py-5 d-none">
|
||||||
<div class="rounded-circle bg-light d-inline-flex p-3 mb-3 text-muted">
|
<div class="rounded-circle bg-light d-inline-flex p-3 mb-3 text-muted">
|
||||||
<i class="bi bi-search fs-1"></i>
|
<i class="bi bi-search fs-1" id="emptyListIcon"></i>
|
||||||
</div>
|
</div>
|
||||||
<h6 class="fw-bold text-secondary">{% translate "Aucun asset trouvé" %}</h6>
|
<h6 class="fw-bold text-secondary" id="emptyListTitle">{% translate "Aucun asset trouvé" %}</h6>
|
||||||
<p class="small text-muted mb-3" id="emptyListSubtitle">{% translate "Modifiez votre recherche ou zoomez sur une autre zone." %}</p>
|
<p class="small text-muted mb-3" id="emptyListSubtitle">{% translate "Modifiez votre recherche ou zoomez sur une autre zone." %}</p>
|
||||||
<div class="d-flex justify-content-center gap-2 flex-wrap">
|
<div class="d-flex justify-content-center gap-2 flex-wrap">
|
||||||
<button type="button" class="btn btn-outline-primary btn-sm rounded-3" id="btnResetFilters">
|
<button type="button" class="btn btn-outline-primary btn-sm rounded-3" id="btnResetFilters">
|
||||||
|
|
@ -594,6 +619,8 @@
|
||||||
let noResultsAlertTimeout = null;
|
let noResultsAlertTimeout = null;
|
||||||
let mapMoveTimeout = null;
|
let mapMoveTimeout = null;
|
||||||
let lastResults = [];
|
let lastResults = [];
|
||||||
|
let lastLimitReached = false;
|
||||||
|
let lastTotalCount = 0;
|
||||||
|
|
||||||
// Éléments DOM
|
// Éléments DOM
|
||||||
const searchInput = document.getElementById('assetSearchInput');
|
const searchInput = document.getElementById('assetSearchInput');
|
||||||
|
|
@ -608,11 +635,15 @@
|
||||||
const viewContainerList = document.getElementById('viewContainerList');
|
const viewContainerList = document.getElementById('viewContainerList');
|
||||||
const assetsListContainer = document.getElementById('assetsListContainer');
|
const assetsListContainer = document.getElementById('assetsListContainer');
|
||||||
const emptyListMessage = document.getElementById('emptyListMessage');
|
const emptyListMessage = document.getElementById('emptyListMessage');
|
||||||
|
const emptyListIcon = document.getElementById('emptyListIcon');
|
||||||
|
const emptyListTitle = document.getElementById('emptyListTitle');
|
||||||
const noThematicSelectedMessage = document.getElementById('noThematicSelectedMessage');
|
const noThematicSelectedMessage = document.getElementById('noThematicSelectedMessage');
|
||||||
const mapThematicPrompt = document.getElementById('mapThematicPrompt');
|
const mapThematicPrompt = document.getElementById('mapThematicPrompt');
|
||||||
const filterLimitAlert = document.getElementById('filterLimitAlert');
|
const filterLimitAlert = document.getElementById('filterLimitAlert');
|
||||||
|
const filterLimitAlertText = document.getElementById('filterLimitAlertText');
|
||||||
const noResultsInZoneAlert = document.getElementById('noResultsInZoneAlert');
|
const noResultsInZoneAlert = document.getElementById('noResultsInZoneAlert');
|
||||||
const btnResetToInitialView = document.getElementById('btnResetToInitialView');
|
const btnResetToInitialView = document.getElementById('btnResetToInitialView');
|
||||||
|
const btnCloseNoResultsAlert = document.getElementById('btnCloseNoResultsAlert');
|
||||||
const btnInitialView = document.getElementById('btnInitialView');
|
const btnInitialView = document.getElementById('btnInitialView');
|
||||||
const btnListInitialView = document.getElementById('btnListInitialView');
|
const btnListInitialView = document.getElementById('btnListInitialView');
|
||||||
const emptyListSubtitle = document.getElementById('emptyListSubtitle');
|
const emptyListSubtitle = document.getElementById('emptyListSubtitle');
|
||||||
|
|
@ -770,10 +801,6 @@
|
||||||
closeBottomSheet();
|
closeBottomSheet();
|
||||||
});
|
});
|
||||||
|
|
||||||
map.on('movestart', () => {
|
|
||||||
hideNoResultsInZoneAlert();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Détection du déplacement ou zoom pour filtrage par zone visible (bbox) et synchronisation de la liste
|
// Détection du déplacement ou zoom pour filtrage par zone visible (bbox) et synchronisation de la liste
|
||||||
map.on('moveend', () => {
|
map.on('moveend', () => {
|
||||||
// Ignorer si la vue active n'est pas la carte ou si aucune thématique n'est choisie
|
// Ignorer si la vue active n'est pas la carte ou si aucune thématique n'est choisie
|
||||||
|
|
@ -930,12 +957,19 @@
|
||||||
// 4. Rendu des résultats sur Carte et dans la Liste
|
// 4. Rendu des résultats sur Carte et dans la Liste
|
||||||
function renderResults(data, fromMapMove = false, options = {}) {
|
function renderResults(data, fromMapMove = false, options = {}) {
|
||||||
lastResults = data.results || [];
|
lastResults = data.results || [];
|
||||||
|
lastLimitReached = Boolean(data.limit_reached);
|
||||||
|
lastTotalCount = data.total_count || 0;
|
||||||
|
|
||||||
// Gestion de la limite de 500 assets atteinte
|
// Gestion de la limite de 500 assets atteinte
|
||||||
if (data.limit_reached) {
|
if (data.limit_reached) {
|
||||||
if (filterLimitAlert) filterLimitAlert.classList.remove('d-none');
|
if (filterLimitAlert) {
|
||||||
if (limitNotice) limitNotice.classList.remove('d-none');
|
filterLimitAlert.classList.remove('d-none');
|
||||||
resultsCountEl.textContent = `${data.count} / ${data.total_count}`;
|
if (filterLimitAlertText && data.total_count) {
|
||||||
|
filterLimitAlertText.textContent = `{% translate "Plus de 500 assets correspondent" %} (${data.total_count} {% translate "au total" %}). {% translate "Veuillez zoomer sur la carte ou affiner vos critères de recherche pour les afficher." %}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (limitNotice) limitNotice.classList.add('d-none');
|
||||||
|
resultsCountEl.textContent = `${data.total_count}`;
|
||||||
} else {
|
} else {
|
||||||
if (filterLimitAlert) filterLimitAlert.classList.add('d-none');
|
if (filterLimitAlert) filterLimitAlert.classList.add('d-none');
|
||||||
if (limitNotice) limitNotice.classList.add('d-none');
|
if (limitNotice) limitNotice.classList.add('d-none');
|
||||||
|
|
@ -952,10 +986,20 @@
|
||||||
handleNoResultsInZoneAlert(data, options);
|
handleNoResultsInZoneAlert(data, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderListView(results) {
|
function renderListView(results = lastResults) {
|
||||||
assetsListContainer.innerHTML = '';
|
assetsListContainer.innerHTML = '';
|
||||||
if (!results || results.length === 0) {
|
if (!results || results.length === 0) {
|
||||||
emptyListMessage.classList.remove('d-none');
|
emptyListMessage.classList.remove('d-none');
|
||||||
|
if (lastLimitReached) {
|
||||||
|
if (emptyListIcon) emptyListIcon.className = 'bi bi-zoom-in fs-1 text-warning';
|
||||||
|
if (emptyListTitle) emptyListTitle.textContent = "{% translate 'Limite de 500 assets atteinte' %}";
|
||||||
|
if (emptyListSubtitle) {
|
||||||
|
emptyListSubtitle.textContent = `{% translate "Plus de 500 assets correspondent" %}${lastTotalCount ? ` (${lastTotalCount} {% translate "au total" %})` : ''}. {% translate "Veuillez zoomer sur la carte ou affiner vos critères de recherche pour afficher la liste." %}`;
|
||||||
|
}
|
||||||
|
if (btnListInitialView) btnListInitialView.classList.add('d-none');
|
||||||
|
} else {
|
||||||
|
if (emptyListIcon) emptyListIcon.className = 'bi bi-search fs-1 text-muted';
|
||||||
|
if (emptyListTitle) emptyListTitle.textContent = "{% translate 'Aucun asset trouvé' %}";
|
||||||
if (btnListInitialView) {
|
if (btnListInitialView) {
|
||||||
if (currentQuery && !isAtMaxBbox()) {
|
if (currentQuery && !isAtMaxBbox()) {
|
||||||
btnListInitialView.classList.remove('d-none');
|
btnListInitialView.classList.remove('d-none');
|
||||||
|
|
@ -969,6 +1013,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
emptyListMessage.classList.add('d-none');
|
emptyListMessage.classList.add('d-none');
|
||||||
|
|
@ -1192,6 +1237,9 @@
|
||||||
// Vérifier si la vue courante correspond à la boîte englobante maximale (vue initiale)
|
// Vérifier si la vue courante correspond à la boîte englobante maximale (vue initiale)
|
||||||
function isAtMaxBbox() {
|
function isAtMaxBbox() {
|
||||||
if (!map) return true;
|
if (!map) return true;
|
||||||
|
// Si la recherche est restreinte par une boîte englobante (zone visible), elle n'est pas à la bbox maximale
|
||||||
|
if (isBboxFiltered) return false;
|
||||||
|
|
||||||
const currentZoom = map.getZoom();
|
const currentZoom = map.getZoom();
|
||||||
const currentCenter = map.getCenter();
|
const currentCenter = map.getCenter();
|
||||||
|
|
||||||
|
|
@ -1199,13 +1247,8 @@
|
||||||
const dLat = Math.abs(currentCenter.lat - defaultCenter[1]);
|
const dLat = Math.abs(currentCenter.lat - defaultCenter[1]);
|
||||||
const zoomDiff = currentZoom - defaultZoom;
|
const zoomDiff = currentZoom - defaultZoom;
|
||||||
|
|
||||||
// Si le zoom est plus grand que le zoom initial (+0.5) ou si le centre s'est décalé (> 0.02 deg ~ 1.5 km)
|
// Si le zoom est plus grand que le zoom initial (+0.5) ou si le centre s'est décalé (> 0.025 deg)
|
||||||
if (zoomDiff > 0.5 || dLng > 0.02 || dLat > 0.02) {
|
if (zoomDiff > 0.5 || dLng > 0.025 || dLat > 0.025) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Si isBboxFiltered est actif et que la position/zoom a bougé
|
|
||||||
if (isBboxFiltered && (zoomDiff > 0.25 || dLng > 0.015 || dLat > 0.015)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1240,6 +1283,12 @@
|
||||||
const count = data.count || (data.results ? data.results.length : 0);
|
const count = data.count || (data.results ? data.results.length : 0);
|
||||||
const hasQuery = Boolean(currentQuery && currentQuery.trim().length > 0);
|
const hasQuery = Boolean(currentQuery && currentQuery.trim().length > 0);
|
||||||
|
|
||||||
|
// Si la limite de 500 est atteinte, ce n'est pas une zone vide : masquer l'alerte de zone vide
|
||||||
|
if (data.limit_reached) {
|
||||||
|
hideNoResultsInZoneAlert();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Si la recherche a retourné des résultats ou si aucune recherche textuelle n'est active, masquer l'alerte
|
// Si la recherche a retourné des résultats ou si aucune recherche textuelle n'est active, masquer l'alerte
|
||||||
if (!hasQuery || count > 0) {
|
if (!hasQuery || count > 0) {
|
||||||
hideNoResultsInZoneAlert();
|
hideNoResultsInZoneAlert();
|
||||||
|
|
@ -1263,9 +1312,9 @@
|
||||||
if (currentQuery && currentQuery.trim().length >= 2 && lastResults.length === 0 && !isAtMaxBbox()) {
|
if (currentQuery && currentQuery.trim().length >= 2 && lastResults.length === 0 && !isAtMaxBbox()) {
|
||||||
showNoResultsInZoneAlert();
|
showNoResultsInZoneAlert();
|
||||||
}
|
}
|
||||||
}, 850);
|
}, 500);
|
||||||
} else {
|
} else {
|
||||||
// Soumission explicite (touche Entrée ou clic loupe)
|
// Soumission explicite (touche Entrée ou clic loupe) ou déplacement de carte
|
||||||
showNoResultsInZoneAlert();
|
showNoResultsInZoneAlert();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1300,6 +1349,9 @@
|
||||||
if (btnResetToInitialView) {
|
if (btnResetToInitialView) {
|
||||||
btnResetToInitialView.addEventListener('click', returnToInitialView);
|
btnResetToInitialView.addEventListener('click', returnToInitialView);
|
||||||
}
|
}
|
||||||
|
if (btnCloseNoResultsAlert) {
|
||||||
|
btnCloseNoResultsAlert.addEventListener('click', hideNoResultsInZoneAlert);
|
||||||
|
}
|
||||||
if (btnInitialView) {
|
if (btnInitialView) {
|
||||||
btnInitialView.addEventListener('click', returnToInitialView);
|
btnInitialView.addEventListener('click', returnToInitialView);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -317,11 +317,13 @@ class MobileAssetDetailTests(TestCase):
|
||||||
self.assertIn("ARB-TEST-001", codes)
|
self.assertIn("ARB-TEST-001", codes)
|
||||||
self.assertIn("ARB-SHRUB-001", codes)
|
self.assertIn("ARB-SHRUB-001", codes)
|
||||||
|
|
||||||
# 3. Test limit reached logic with limit=1
|
# 3. Test limit reached logic with limit=1: when limit is reached, return empty results and empty geojson
|
||||||
response = self.client.get(search_url, {"thematic": "nature", "limit": "1"})
|
response = self.client.get(search_url, {"thematic": "nature", "limit": "1"})
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
data = response.json()
|
data = response.json()
|
||||||
self.assertEqual(data["count"], 1)
|
self.assertEqual(data["count"], 0)
|
||||||
|
self.assertEqual(data["results"], [])
|
||||||
|
self.assertEqual(data["geojson"]["features"], [])
|
||||||
self.assertEqual(data["limit"], 1)
|
self.assertEqual(data["limit"], 1)
|
||||||
self.assertTrue(data["limit_reached"])
|
self.assertTrue(data["limit_reached"])
|
||||||
self.assertGreater(data["total_count"], 1)
|
self.assertGreater(data["total_count"], 1)
|
||||||
|
|
|
||||||
|
|
@ -1348,8 +1348,7 @@ def mobile_assets_search(request):
|
||||||
c = 2.0 * math.atan2(math.sqrt(a), math.sqrt(max(0.0, 1.0 - a)))
|
c = 2.0 * math.atan2(math.sqrt(a), math.sqrt(max(0.0, 1.0 - a)))
|
||||||
return R * c
|
return R * c
|
||||||
|
|
||||||
results = []
|
model_querysets = []
|
||||||
features = []
|
|
||||||
total_count = 0
|
total_count = 0
|
||||||
|
|
||||||
t_code = thematic_filter
|
t_code = thematic_filter
|
||||||
|
|
@ -1386,10 +1385,30 @@ def mobile_assets_search(request):
|
||||||
# Nombre total d'assets correspondants (pour savoir si limite atteinte)
|
# Nombre total d'assets correspondants (pour savoir si limite atteinte)
|
||||||
count_for_model = qs.count()
|
count_for_model = qs.count()
|
||||||
total_count += count_for_model
|
total_count += count_for_model
|
||||||
|
model_querysets.append((model_key, model_class, qs))
|
||||||
|
|
||||||
remaining_slots = limit - len(results)
|
limit_reached = total_count > limit
|
||||||
if remaining_slots > 0:
|
|
||||||
items = list(qs[:remaining_slots])
|
# Si la limite est atteinte, ne renvoyer aucun asset ni GeoJSON pour ne pas induire en erreur et alléger la requête
|
||||||
|
if limit_reached:
|
||||||
|
return JsonResponse({
|
||||||
|
'count': 0,
|
||||||
|
'total_count': total_count,
|
||||||
|
'limit': limit,
|
||||||
|
'limit_reached': True,
|
||||||
|
'thematic': t_code,
|
||||||
|
'results': [],
|
||||||
|
'geojson': {
|
||||||
|
'type': 'FeatureCollection',
|
||||||
|
'features': [],
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
results = []
|
||||||
|
features = []
|
||||||
|
|
||||||
|
for model_key, model_class, qs in model_querysets:
|
||||||
|
items = list(qs)
|
||||||
for item in items:
|
for item in items:
|
||||||
lat = None
|
lat = None
|
||||||
lon = None
|
lon = None
|
||||||
|
|
@ -1483,19 +1502,16 @@ def mobile_assets_search(request):
|
||||||
else:
|
else:
|
||||||
results.sort(key=lambda x: x['code'])
|
results.sort(key=lambda x: x['code'])
|
||||||
|
|
||||||
results = results[:limit]
|
|
||||||
limit_reached = total_count > limit
|
|
||||||
|
|
||||||
return JsonResponse({
|
return JsonResponse({
|
||||||
'count': len(results),
|
'count': len(results),
|
||||||
'total_count': total_count,
|
'total_count': total_count,
|
||||||
'limit': limit,
|
'limit': limit,
|
||||||
'limit_reached': limit_reached,
|
'limit_reached': False,
|
||||||
'thematic': t_code,
|
'thematic': t_code,
|
||||||
'results': results,
|
'results': results,
|
||||||
'geojson': {
|
'geojson': {
|
||||||
'type': 'FeatureCollection',
|
'type': 'FeatureCollection',
|
||||||
'features': features[:limit],
|
'features': features,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue