Ajout d'une carte de tous les lieux

This commit is contained in:
Jean-Marie Favreau 2024-07-06 15:23:21 +02:00
parent 4c431e515d
commit d36dbe17a0
8 changed files with 142 additions and 51 deletions

View File

@ -250,6 +250,9 @@ class Place(models.Model):
def nb_events(self):
return Event.objects.filter(exact_location=self).count()
def nb_events_future(self):
return Event.objects.filter(start_day__gte=datetime.now()).filter(exact_location=self).count()
def match(self, event):
if self.aliases:
return event.location in self.aliases

View File

@ -85,6 +85,9 @@
<div>
<a href="{% url 'mentions_legales' %}">Mentions légales</a>
</div>
<div>
<a href="{% url 'view_places' %}">Lieux</a>
</div>
<div>
<a href="{% url 'about' %}">À propos</a>
</div>

View File

@ -23,7 +23,7 @@
<article>
<header>
{% if perms.agenda_culturel.change_place %}
<a href="{% url 'view_places' %}" role="button">&lt; Tous les lieux</a>
<a href="{% url 'view_places_admin' %}" role="button">&lt; Tous les lieux</a>
{% endif %}
{% if perms.agenda_culturel.change_place %}
<div class="slide-buttons">
@ -38,11 +38,14 @@
<ul>
<li><strong>Adresse&nbsp;:</strong> {{ object.address }}, {{ object.city }}</li>
<li><strong>Coordonnée GPS&nbsp;:</strong> <a href="geo:{{ object.location }}">{{ object.location }}</a></li>
{% if object.nb_events > 0 %}
<li><strong>Nombre d'événements&nbsp;:</strong> {{ object.nb_events }}</li>
{% else %}
<li><em>Aucun événement n'est enregistré dans ce lieu</em></li>
{% endif %}
{% with place.nb_events_future as nb %}
{% if nb > 0 %}
<li>{{ nb }} événement{{ nb|pluralize }} à venir</li>
{% else %}
<li><em>Aucun événement à venir</em></li>
{% endif %}
{% endwith %}
</ul>
</div>
<div>
@ -56,10 +59,11 @@
}).addTo(map);
var marker = L.marker([{{ object.location }}]).addTo(map);
</script>
<p>Voir aussi <a href="{% url 'view_places' %}">les autres lieux</a></p>
</div>
</div>
{% if object_list %}
<h2>Événements</h2>
<h2>Événements du lieu</h2>
{% include "agenda_culturel/navigation.html" with page_obj=page_obj %}

View File

@ -1,63 +1,71 @@
{% extends "agenda_culturel/page.html" %}
{% block title %}Questions de modération{% endblock %}
{% block title %}Lieux{% endblock %}
{% load utils_extra %}
{% load static %}
{% load cat_extra %}
{% block entete_header %}
{% css_categories %}
<script src="/static/admin/js/vendor/jquery/jquery.js"></script>
<script src="/static/admin/js/jquery.init.js"></script>
<script src="{% static 'location_field/leaflet/leaflet.js' %}"></script>
<link href="{% static 'location_field/leaflet/leaflet.css' %}" type="text/css" media="all" rel="stylesheet">
{% endblock %}
{% block fluid %}{% endblock %}
{% block content %}
<div class="grid two-columns">
<article>{% include "agenda_culturel/static_content.html" with name="places" url_path="/places" %}</article>
<article>
<header>
<div class="slide-buttons">
<a href="{% url 'fix_unknown_places' %}" role="button" data-tooltip="Utiliser les alias des lieux pour les associer aux événements sans lieu">Détecter par alias {% picto_from_name "link" %}</a>
<a href="{% url 'add_place' %}" role="button">Ajouter {% picto_from_name "plus-circle" %}</a>
<a href="{% url 'view_places_admin' %}" role="button" data-tooltip="Administrer les lieux">Administrer</a>
</div>
<h1>Lieux</h1>
<h1>Les lieux</h1>
</header>
{% include "agenda_culturel/navigation.html" with page_obj=page_obj %}
<div class="grid">
<div id="map_location" style="width: 100%; aspect-ratio: 16/16"></div>
{% if object_list %}
{% for place in object_list %}
<article>
<header>
<div class="slide-buttons">
<a href="{% url 'view_place' place.pk %}" role="button">Consulter {% picto_from_name "eye" %}</a>
<a href="{% url 'edit_place' place.pk %}" role="button">Modifier {% picto_from_name "edit-3" %}</a>
<a href="{% url 'delete_place' place.pk %}" role="button">Supprimer {% picto_from_name "trash-2" %}</a>
</div>
<h2>{{ place.name }}</h2>
<div>
{% if object_list %}
{% for place in object_list %}
<h3><a href="{% url 'view_place' place.pk %}">{{ place.name }}</a></h3>
<ul>
<li><strong>Adresse&nbsp;:</strong> {{ place.address }}, {{ place.city }}</li>
<li><strong>Adresse&nbsp;:</strong> {% if place.address %}{{ place.address }}, {% endif %}{{ place.city }}</li>
<li><strong>Coordonnée GPS&nbsp;:</strong> {{ place.location }}</li>
{% with place.nb_events_future as nb %}
{% if nb > 0 %}
<li>{{ nb }} événement{{ nb|pluralize }} à venir</li>
{% endif %}
{% endwith %}
</ul>
{% if place.aliases|length > 0 %}
<p><strong>Alias&nbsp;:</strong> {% for alias in place.aliases %}{{ alias }}{% if not forloop.last %}, {% endif %}{% endfor %} </p>
{% else %}
<p><em>Ce lieu n'a pas d'alias défini</em></p>
{% endif %}
{% if place.nb_events > 0 %}
<p><strong>Nombre d'événements&nbsp;:</strong> {{ place.nb_events }}</p>
{% else %}
<p><em>Aucun événement n'est enregistré dans ce lieu</em></p>
{% endif %}
</header>
</article>
{% endfor %}
{% else %}
<p>Il n'y a aucun lieu défini.</p>
{% endif %}
<footer>
{% include "agenda_culturel/navigation.html" with page_obj=page_obj %}
</footer>
{% endfor %}
{% else %}
<p>Il n'y a aucun lieu défini.</p>
{% endif %}
</div>
</div>
</article>
{% include "agenda_culturel/side-nav.html" with current="places" %}
</div>
<script>
L.Icon.Default.imagePath = "{% static "location_field/leaflet/images/" %}";
var map = L.map('map_location');
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);
var markerArray = [];
{% if object_list %}
{% for place in object_list %}
markerArray.push(L.marker([{{ place.location }}]).bindPopup('<a href="{% url 'view_place' place.pk %}">{{ place.name }}</a><br />{% if place.address %}{{ place.address }}, {% endif %}{{ place.city }}'));
{% endfor %}
{% endif %}
var group = L.featureGroup(markerArray).addTo(map);
map.fitBounds(group.getBounds());
</script>
{% endblock %}

View File

@ -0,0 +1,64 @@
{% extends "agenda_culturel/page.html" %}
{% block title %}Administration des lieux{% endblock %}
{% load utils_extra %}
{% load cat_extra %}
{% block entete_header %}
{% css_categories %}
{% endblock %}
{% block content %}
<div class="grid two-columns">
<article>
<header>
<div class="slide-buttons">
<a href="{% url 'view_places' %}" role="button" data-tooltip="Voir la carte">Carte {% picto_from_name "map" %}</a>
<a href="{% url 'fix_unknown_places' %}" role="button" data-tooltip="Utiliser les alias des lieux pour les associer aux événements sans lieu">Détecter par alias {% picto_from_name "link" %}</a>
<a href="{% url 'add_place' %}" role="button">Ajouter {% picto_from_name "plus-circle" %}</a>
</div>
<h1>Lieux</h1>
</header>
{% include "agenda_culturel/navigation.html" with page_obj=page_obj %}
{% if object_list %}
{% for place in object_list %}
<article>
<header>
<div class="slide-buttons">
<a href="{% url 'view_place' place.pk %}" role="button">Consulter {% picto_from_name "eye" %}</a>
<a href="{% url 'edit_place' place.pk %}" role="button">Modifier {% picto_from_name "edit-3" %}</a>
<a href="{% url 'delete_place' place.pk %}" role="button">Supprimer {% picto_from_name "trash-2" %}</a>
</div>
<h2>{{ place.name }}</h2>
<ul>
<li><strong>Adresse&nbsp;:</strong> {{ place.address }}, {{ place.city }}</li>
<li><strong>Coordonnée GPS&nbsp;:</strong> {{ place.location }}</li>
</ul>
{% if place.aliases|length > 0 %}
<p><strong>Alias&nbsp;:</strong> {% for alias in place.aliases %}{{ alias }}{% if not forloop.last %}, {% endif %}{% endfor %} </p>
{% else %}
<p><em>Ce lieu n'a pas d'alias défini</em></p>
{% endif %}
{% if place.nb_events > 0 %}
<p><strong>Nombre d'événements&nbsp;:</strong> {{ place.nb_events }}</p>
{% else %}
<p><em>Aucun événement n'est enregistré dans ce lieu</em></p>
{% endif %}
</header>
</article>
{% endfor %}
{% else %}
<p>Il n'y a aucun lieu défini.</p>
{% endif %}
<footer>
{% include "agenda_culturel/navigation.html" with page_obj=page_obj %}
</footer>
</article>
{% include "agenda_culturel/side-nav.html" with current="places" %}
</div>
{% endblock %}

View File

@ -18,17 +18,19 @@
<li><a {% if current == "tags" %}class="selected" {% endif %}href="{% url 'view_all_tags' %}">Consulter les étiquettes</a></li>
</ul>
</nav>
{% if perms.agenda_culturel.change_place %}
<h3>Lieux</h3>
<nav>
<ul>
{% if perms.agenda_culturel.change_place %}
<li><a {% if current == "places" %}class="selected" {% endif %}href="{% url 'view_places' %}">Liste des lieux</a></li>
<li><a {% if current == "places" %}class="selected" {% endif %}href="{% url 'view_places_admin' %}">Liste des lieux</a></li>
{% endif %}
{% if perms.agenda_culturel.change_place and perms.agenda_culturel.change_event %}
<li><a {% if current == "unknown_places" %}class="selected" {% endif %}href="{% url 'view_unknown_places' %}">Événements sans lieu</a>{% show_badge_unknown_places "left" %}</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% if perms.agenda_culturel.view_batchimportation or perms.agenda_culturel.view_recurrentimport or perms.agenda_culturel.view_categorisationrule%}
<h3>Traitements automatiques</h3>
<nav>

View File

@ -141,6 +141,7 @@ urlpatterns = [
path("place/<int:pk>/edit", PlaceUpdateView.as_view(), name="edit_place"),
path("place/<int:pk>/delete", PlaceDeleteView.as_view(), name="delete_place"),
path("places/", PlaceListView.as_view(), name="view_places"),
path("places/list", PlaceListAdminView.as_view(), name="view_places_admin"),
path("places/add", PlaceCreateView.as_view(), name="add_place"),
path(
"places/add/<int:pk>",

View File

@ -1541,9 +1541,15 @@ class ModerationAnswerDeleteView(PermissionRequiredMixin, DeleteView):
class PlaceListView(ListView):
model = Place
paginate_by = 10
ordering = ["name__unaccent"]
class PlaceListAdminView(PermissionRequiredMixin, ListView):
model = Place
paginate_by = 10
permission_required = "agenda_culturel.add_place"
ordering = ["name__unaccent"]
template_name = "agenda_culturel/place_list_admin.html"
class PlaceDetailView(ListView):
model = Place
@ -1604,7 +1610,7 @@ class PlaceCreateView(
class PlaceDeleteView(PermissionRequiredMixin, DeleteView):
model = Place
permission_required = "agenda_culturel.delete_place"
success_url = reverse_lazy("view_places")
success_url = reverse_lazy("view_places_admin")
class UnknownPlacesListView(PermissionRequiredMixin, ListView):