diff --git a/src/backoffice/templates/maps_feature_form.html b/src/backoffice/templates/maps_feature_form.html index 433bfd864..47d63436b 100644 --- a/src/backoffice/templates/maps_feature_form.html +++ b/src/backoffice/templates/maps_feature_form.html @@ -4,9 +4,15 @@ {% load static %} {% block extra_head %} + + + {{ form.media }} {% leaflet_css plugins="forms" %} {% leaflet_js plugins="forms" %} + + + {{ mapData|json_script:"mapData" }} diff --git a/src/backoffice/views/maps.py b/src/backoffice/views/maps.py index 2a739df3b..7706037d0 100644 --- a/src/backoffice/views/maps.py +++ b/src/backoffice/views/maps.py @@ -9,7 +9,6 @@ from django.contrib.gis.geos import GEOSGeometry from django.db.models import Q from django.http import HttpResponseRedirect -from django.templatetags.static import static from django.urls import reverse from django.views.generic import ListView from django.views.generic.edit import CreateView @@ -22,6 +21,7 @@ from camps.mixins import CampViewMixin from maps.mixins import ExternalLayerMapperViewMixin from maps.mixins import GisTeamViewMixin +from maps.mixins import LayerMapMixin from maps.mixins import LayerMapperViewMixin from maps.models import ExternalLayer from maps.models import Feature @@ -33,16 +33,18 @@ logger = logging.getLogger(f"bornhack.{__name__}") - # ################# LAYERS ######################## class MapLayerListView(CampViewMixin, AnyTeamMapperRequiredMixin, ListView): + """View for the list of layers.""" + model = Layer template_name = "maps_layer_list_backoffice.html" context_object_name = "maps_layer_list" def get_context_data(self, **kwargs): + """Method to get the list of layers.""" context = super().get_context_data(**kwargs) context["layers"] = Layer.objects.filter( Q(responsible_team__camp=self.camp) | Q(responsible_team=None), @@ -267,7 +269,7 @@ def get_context_data(self, **kwargs): return context -class MapFeatureCreateView(LayerMapperViewMixin, CreateView): +class MapFeatureCreateView(LayerMapperViewMixin, LayerMapMixin, CreateView): model = Feature template_name = "maps_feature_form.html" fields = [ @@ -284,7 +286,7 @@ class MapFeatureCreateView(LayerMapperViewMixin, CreateView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context["mapData"] = {"grid": static("json/grid.geojson")} + context.update({"mapData": self.get_map_data()}) return context def get_form(self, *args, **kwargs): @@ -313,7 +315,7 @@ def get_success_url(self): ) -class MapFeatureUpdateView(LayerMapperViewMixin, UpdateView): +class MapFeatureUpdateView(LayerMapperViewMixin, LayerMapMixin, UpdateView): model = Feature slug_url_kwarg = "feature_uuid" slug_field = "uuid" @@ -331,7 +333,7 @@ class MapFeatureUpdateView(LayerMapperViewMixin, UpdateView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context["mapData"] = {"grid": static("json/grid.geojson")} + context.update({"mapData": self.get_map_data()}) return context def get_form(self, *args, **kwargs): diff --git a/src/maps/mixins.py b/src/maps/mixins.py index f37ce7014..a36ceab77 100644 --- a/src/maps/mixins.py +++ b/src/maps/mixins.py @@ -5,13 +5,18 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: + from django.db.models import QuerySet from django.http import HttpRequest from django.contrib import messages from django.core.exceptions import PermissionDenied +from django.db.models import Q from django.shortcuts import get_object_or_404 +from django.templatetags.static import static +from django.urls import reverse from camps.mixins import CampViewMixin +from facilities.models import FacilityType from .models import ExternalLayer from .models import Layer @@ -99,3 +104,69 @@ def setup(self, request: HttpRequest, *args, **kwargs) -> None: return messages.error(request, "No thanks") raise PermissionDenied + + +class LayerMapMixin: + """Mixin for loading the map data from the layers.""" + + camp_slug = None + + def setup(self, request: HttpRequest, *args, **kwargs) -> None: + """Class init method.""" + super().setup(request, *args, **kwargs) + self.camp_slug = kwargs["camp_slug"] + + def get_layers(self) -> QuerySet: + """Method to get the layers the user has access to.""" + user_teams = [] + if not self.request.user.is_anonymous: + user_teams = self.request.user.teammember_set.filter( + team__camp__slug=self.camp_slug, + ).values_list("team__name", flat=True) + return Layer.objects.filter( + ((Q(responsible_team__camp__slug=self.camp_slug) | Q(responsible_team=None)) & Q(public=True)) + | (Q(responsible_team__name__in=user_teams) & Q(public=False)), + ) + + def get_map_data(self) -> dict: + """Method to return the map_data.""" + map_data = { + "grid": static("json/grid.geojson"), + "loggedIn": self.request.user.is_authenticated, + "layers": [], + "facilitytype_list": [], + } + facilitytype_list = FacilityType.objects.filter( + responsible_team__camp__slug=self.camp_slug, + ) + map_data.update({"facilitytype_list": list(facilitytype_list.values())}) + layers = self.get_layers() + map_data.update( + { + "layers": list( + layers.values( + "description", + "name", + "slug", + "uuid", + "icon", + "invisible", + "group__name", + ), + ), + }, + ) + for facility in map_data["facilitytype_list"]: + facility["url"] = reverse( + "facilities:facility_list_geojson", + kwargs={ + "camp_slug": self.camp_slug, + "facility_type_slug": facility["slug"], + }, + ) + for layer in map_data["layers"]: + layer["url"] = reverse( + "maps:map_layer_geojson", + kwargs={"layer_slug": layer["slug"]}, + ) + return map_data diff --git a/src/static_src/js/maps/generic/init_loader.js b/src/static_src/js/maps/generic/init_loader.js index ed1d0e6bd..598a20ec1 100644 --- a/src/static_src/js/maps/generic/init_loader.js +++ b/src/static_src/js/maps/generic/init_loader.js @@ -1,11 +1,14 @@ const mapData = JSON.parse( document.getElementById('mapData').textContent ); - +const loggedIn = mapData['loggedIn'] var mapObject = undefined; window.addEventListener("map:init", function (event) { var map = event.detail.map; mapObject = new BHMap(map); + mapObject.map.addControl(new L.Control.Fullscreen({ + pseudoFullscreen: true, + })); if (mapData.grid) { mapObject.loadLayer(mapData.grid, "Grid squares", { onEachFeature: mapObject.onEachGrid, @@ -16,6 +19,27 @@ window.addEventListener("map:init", function (event) { }, }); } + if (mapData.facilitytype_list) { + mapData['facilitytype_list'].forEach(function (item) { + mapObject.loadLayer(item.url, item.name, facilityOptions, true, function(){}, "Facilities", item.icon); + }) + } + if (mapData.layers) { + mapData['layers'].forEach(function (item) { + mapObject.loadLayer(item.url, item.name, { + onEachFeature: function(feature, layer) { + if (feature.properties.color !== "#FFFFFFFF") { + layer.setStyle({ + color: feature.properties.color + }) + } + }, + style: { + color: "{{ layer.color }}" + } + }); + }); + } });