style osmose dashboard

This commit is contained in:
Tykayn 2025-08-31 18:34:19 +02:00 committed by tykayn
parent 684bf1da66
commit e715d66020
2 changed files with 74 additions and 103 deletions

View file

@ -2588,8 +2588,8 @@ final class AdminController extends AbstractController
if ($this->isPointInCity($issue['lat'], $issue['lon'], $lat, $lon, 10)) { if ($this->isPointInCity($issue['lat'], $issue['lon'], $lat, $lon, 10)) {
$issues[] = [ $issues[] = [
'id' => $issue['id'] ?? '', 'id' => $issue['id'] ?? '',
'title' => $issue['title'] ?? 'Problème sans titre', 'title' => $issue['properties']['title'] ?? 'Problème sans titre',
'subtitle' => $issue['subtitle'] ?? '', 'subtitle' => $issue['properties']['subtitle'] ?? '',
'lat' => $issue['lat'], 'lat' => $issue['lat'],
'lon' => $issue['lon'], 'lon' => $issue['lon'],
'item' => $issue['item'] ?? '', 'item' => $issue['item'] ?? '',

View file

@ -5,10 +5,18 @@
{% block stylesheets %} {% block stylesheets %}
{{ parent() }} {{ parent() }}
<style> <style>
.maplibregl-ctrl-group button{
padding: 1.5rem;
}
.maplibregl-popup{
z-index: 100;
}
#map { #map {
height: 70vh; height: 70vh;
width: 100%; width: 100%;
margin-bottom: 20px; margin-bottom: 430px;
} }
.filters { .filters {
margin-bottom: 20px; margin-bottom: 20px;
@ -36,24 +44,7 @@
.issue-item.level-3 { .issue-item.level-3 {
border-left-color: #ffc107; /* Jaune pour les avertissements */ border-left-color: #ffc107; /* Jaune pour les avertissements */
} }
.marker-cluster-small { /* Styles de clustering supprimés car le clustering est désactivé */
background-color: rgba(181, 226, 140, 0.6);
}
.marker-cluster-small div {
background-color: rgba(110, 204, 57, 0.6);
}
.marker-cluster-medium {
background-color: rgba(241, 211, 87, 0.6);
}
.marker-cluster-medium div {
background-color: rgba(240, 194, 12, 0.6);
}
.marker-cluster-large {
background-color: rgba(253, 156, 115, 0.6);
}
.marker-cluster-large div {
background-color: rgba(241, 128, 23, 0.6);
}
.marker-level-1 { .marker-level-1 {
background-color: #dc3545; background-color: #dc3545;
border-radius: 50%; border-radius: 50%;
@ -324,58 +315,16 @@
type: 'FeatureCollection', type: 'FeatureCollection',
features: features features: features
}, },
cluster: true, cluster: false // Désactiver le clustering comme demandé
clusterMaxZoom: 14,
clusterRadius: 50
}); });
// Ajouter une couche pour les clusters // Avec le clustering désactivé, nous n'avons plus besoin des couches de clusters
// Ajouter une couche pour les points (sans filtre de clustering puisqu'il est désactivé)
map.addLayer({ map.addLayer({
id: 'clusters', id: 'point',
type: 'circle', type: 'circle',
source: 'issues', source: 'issues',
filter: ['has', 'point_count'],
paint: {
'circle-color': [
'step',
['get', 'point_count'],
'rgba(181, 226, 140, 0.6)',
10,
'rgba(241, 211, 87, 0.6)',
30,
'rgba(253, 156, 115, 0.6)'
],
'circle-radius': [
'step',
['get', 'point_count'],
20,
10,
30,
30,
40
]
}
});
// Ajouter une couche pour le nombre de points dans chaque cluster
map.addLayer({
id: 'cluster-count',
type: 'symbol',
source: 'issues',
filter: ['has', 'point_count'],
layout: {
'text-field': '{point_count_abbreviated}',
'text-font': ['DIN Offc Pro Medium', 'Arial Unicode MS Bold'],
'text-size': 12
}
});
// Ajouter une couche pour les points individuels
map.addLayer({
id: 'unclustered-point',
type: 'circle',
source: 'issues',
filter: ['!', ['has', 'point_count']],
paint: { paint: {
'circle-color': [ 'circle-color': [
'match', 'match',
@ -391,45 +340,73 @@
} }
}); });
// Ajouter un événement de clic sur les clusters // Avec le clustering désactivé, nous n'avons plus besoin de l'événement de clic sur les clusters
map.on('click', 'clusters', function(e) {
const features = map.queryRenderedFeatures(e.point, { layers: ['clusters'] });
const clusterId = features[0].properties.cluster_id;
map.getSource('issues').getClusterExpansionZoom(clusterId, function(err, zoom) {
if (err) return;
map.easeTo({
center: features[0].geometry.coordinates,
zoom: zoom
});
});
});
// Ajouter un événement de clic sur les points individuels // Ajouter un événement de clic sur les points individuels
map.on('click', 'unclustered-point', function(e) { map.on('click', 'point', function(e) {
const coordinates = e.features[0].geometry.coordinates.slice(); const coordinates = e.features[0].geometry.coordinates.slice();
const title = e.features[0].properties.title; const properties = e.features[0].properties;
const subtitle = e.features[0].properties.subtitle;
const item = e.features[0].properties.item;
const url = e.features[0].properties.url;
// Créer le contenu de la popup // Extraire toutes les propriétés disponibles
const id = properties.id || 'N/A';
const title = properties.title || 'Problème sans titre';
const subtitle = properties.subtitle || '';
const lat = e.features[0].geometry.coordinates[1];
const lon = e.features[0].geometry.coordinates[0];
const item = properties.item || '';
const itemClass = properties.class || '';
const level = properties.level || '';
const updateTimestamp = properties.update_timestamp ? new Date(properties.update_timestamp * 1000).toLocaleString() : 'N/A';
const url = properties.url || '#';
// Créer le contenu de la popup avec toutes les propriétés
let popupContent = ` let popupContent = `
<div class="popup-content" style="max-width: 300px;">
<h5>${title}</h5> <h5>${title}</h5>
`; `;
if (subtitle) { if (subtitle) {
popupContent += `<p>${subtitle}</p>`; popupContent += `<p class="text-muted">${subtitle}</p>`;
} }
// Ajouter toutes les propriétés dans un tableau
popupContent += ` popupContent += `
<div> <table class="table table-sm table-bordered mt-2">
<span class="badge bg-secondary">Item: ${item}</span> <tbody>
</div> <tr>
<th>ID</th>
<td>${id}</td>
</tr>
<tr>
<th>Coordonnées</th>
<td>${lat.toFixed(6)}, ${lon.toFixed(6)}</td>
</tr>
<tr>
<th>Item</th>
<td>${item}</td>
</tr>
<tr>
<th>Classe</th>
<td>${itemClass}</td>
</tr>
<tr>
<th>Niveau</th>
<td>
<span class="badge ${level == 1 ? 'bg-danger' : level == 2 ? 'bg-warning text-dark' : 'bg-info'}">
${level == 1 ? 'Critique' : level == 2 ? 'Important' : 'Avertissement'}
</span>
</td>
</tr>
<tr>
<th>Dernière mise à jour</th>
<td>${updateTimestamp}</td>
</tr>
</tbody>
</table>
<div class="mt-2"> <div class="mt-2">
<a href="${url}" target="_blank" class="btn btn-sm btn-primary">Voir sur Osmose</a> <a href="${url}" target="_blank" class="btn btn-sm btn-primary">Voir sur Osmose</a>
</div> </div>
</div>
`; `;
// Assurer que si le zoom change, la popup reste à la bonne position // Assurer que si le zoom change, la popup reste à la bonne position
@ -443,17 +420,11 @@
.addTo(map); .addTo(map);
}); });
// Changer le curseur au survol des clusters et des points // Changer le curseur au survol des points
map.on('mouseenter', 'clusters', function() { map.on('mouseenter', 'point', function() {
map.getCanvas().style.cursor = 'pointer'; map.getCanvas().style.cursor = 'pointer';
}); });
map.on('mouseleave', 'clusters', function() { map.on('mouseleave', 'point', function() {
map.getCanvas().style.cursor = '';
});
map.on('mouseenter', 'unclustered-point', function() {
map.getCanvas().style.cursor = 'pointer';
});
map.on('mouseleave', 'unclustered-point', function() {
map.getCanvas().style.cursor = ''; map.getCanvas().style.cursor = '';
}); });
@ -467,7 +438,7 @@
// Simuler un clic sur le point pour ouvrir la popup // Simuler un clic sur le point pour ouvrir la popup
const features = map.queryRenderedFeatures( const features = map.queryRenderedFeatures(
map.project([lon, lat]), map.project([lon, lat]),
{ layers: ['unclustered-point'] } { layers: ['point'] }
); );
if (features.length > 0) { if (features.length > 0) {