From 309169ceedb7ba6f346f9bc1573c3a376d086134 Mon Sep 17 00:00:00 2001
From: xaralis <filip.varecha@fragaria.cz>
Date: Mon, 20 Jun 2022 11:40:54 +0200
Subject: [PATCH] refactor(district): fix/unify js map handling for both block
 and page-based approach

---
 district/models.py                            | 14 ++----
 maps_utils/blocks.py                          | 45 +++++++++----------
 .../maps_utils/geo-feature-collection.js      | 32 +++++++------
 3 files changed, 44 insertions(+), 47 deletions(-)

diff --git a/district/models.py b/district/models.py
index 19cff274..715f307b 100644
--- a/district/models.py
+++ b/district/models.py
@@ -1647,7 +1647,7 @@ class DistrictGeoFeatureDetailPage(
     def as_geojson_object(self, request):
         collection = json.loads(self.geojson)
         image = (
-            self.image.get_rendition("fill-800x450|jpegquality-80").url
+            self.image.get_rendition("fill-1200x675|jpegquality-80").url
             if self.image
             else None
         )
@@ -1667,23 +1667,15 @@ class DistrictGeoFeatureDetailPage(
                 }
             )
 
-            feature["properties"]["selfTitle"] = feature["properties"].get("title")
-
-            feature["properties"]["title"] = (
-                feature["properties"]["title"] + " - " + self.title
-                if feature["properties"]["selfTitle"]
-                else self.title
-            )
-
             if not "description" in feature["properties"]:
                 feature["properties"]["description"] = None
 
         # This extends GeoJSON spec to pass down more context to the map.
         collection["properties"] = {}
         collection["properties"]["slug"] = f"{self.pk}-{self.slug}"
-        collection["properties"]["title"] = self.title
-        collection["properties"]["category"] = self.category.name
+        collection["properties"]["collectionTitle"] = self.title
         collection["properties"]["collectionDescription"] = self.perex
+        collection["properties"]["category"] = self.category.name
         collection["properties"]["index"] = self.index
         collection["properties"]["image"] = image
         collection["properties"]["link"] = url
diff --git a/maps_utils/blocks.py b/maps_utils/blocks.py
index 8c8086a1..161cb8f6 100644
--- a/maps_utils/blocks.py
+++ b/maps_utils/blocks.py
@@ -50,6 +50,8 @@ class MapPointBlock(blocks.StructBlock):
                         "properties": {
                             "slug": feature_id,
                             "title": None,
+                            "collectionTitle": None,
+                            "collectionDescription": None,
                         },
                         "features": [
                             {
@@ -66,6 +68,7 @@ class MapPointBlock(blocks.StructBlock):
                                     "slug": feature_id,
                                     "title": None,
                                     "description": None,
+                                    "collectionTitle": None,
                                     "collectionDescription": None,
                                     "image": None,
                                     "color": value["hex_color"],
@@ -139,11 +142,14 @@ class MapFeatureCollectionBlock(blocks.StructBlock):
             fwp["properties"].update(
                 {
                     "id": feature_id,
-                    "slug": f"{feature_id}-{slugify(feature['title'])}",
-                    "collectionTItle": feature["title"],
+                    "slug": f"0-{feature_id}-{slugify(feature['title'])}",
+                    # Individual features are suppressed to emulate collection-like style.
+                    "title": None,
+                    "description": None,
+                    "collectionTitle": feature["title"],
                     "collectionDescription": feature["description"],
                     "image": feature["image"]
-                    .get_rendition("fill-800x450|jpegquality-80")
+                    .get_rendition("fill-1200x675|jpegquality-80")
                     .url
                     if feature["image"]
                     else None,
@@ -151,38 +157,31 @@ class MapFeatureCollectionBlock(blocks.StructBlock):
                     "color": feature["hex_color"],
                 }
             )
-
-            fwp["properties"]["selfTitle"] = fwp["properties"].get("title")
-
-            fwp["properties"]["title"] = (
-                fwp["properties"]["title"] + " - " + feature["title"]
-                if fwp["properties"]["selfTitle"]
-                else self.title
-            )
-
-            if not "description" in fwp["properties"]:
-                fwp["properties"]["description"] = None
-
             return fwp
 
+        features = [
+            _geojson_feature_with_props(i, f) for i, f in enumerate(value["features"])
+        ]
+
         context = super().get_context(value, parent_context)
-        collection_id = str(uuid4())
         context["js_map"] = {
             "tile_server_config": json.dumps(TILE_SERVER_CONFIG),
             "geojson": json.dumps(
                 [
+                    # Each feature dumped as individual collection to make things consistent.
                     {
-                        # Dump individual features in collection
                         "type": "FeatureCollection",
                         "properties": {
-                            "slug": collection_id,
-                            "title": None,
+                            "slug": f"{f['properties']['id']}-{slugify(f['properties']['collectionTitle'])}",
+                            "collectionTitle": f["properties"]["collectionTitle"],
+                            "collectionDescription": f["properties"][
+                                "collectionDescription"
+                            ],
+                            "image": f["properties"]["image"],
                         },
-                        "features": [
-                            _geojson_feature_with_props(i, f)
-                            for i, f in enumerate(value["features"])
-                        ],
+                        "features": [f],
                     }
+                    for f in features
                 ]
             ),
         }
diff --git a/maps_utils/static/maps_utils/geo-feature-collection.js b/maps_utils/static/maps_utils/geo-feature-collection.js
index c466987a..4edbf101 100644
--- a/maps_utils/static/maps_utils/geo-feature-collection.js
+++ b/maps_utils/static/maps_utils/geo-feature-collection.js
@@ -372,6 +372,8 @@ const GeoFeatureCollection = Vue.component("GeoFeatureCollection", {
                     : buildMarkerIcon("000000", number);
 
             const addMarker = (feature, markerPosLatLng, onClick) => {
+                const tooltipTitle = [feature.properties.title, feature.properties.collectionTitle].filter(i => !!i).join(' - ');
+
                 // add marker
                 const featureMarker = new L.marker(markerPosLatLng, {
                     icon: feature.properties.color
@@ -385,7 +387,7 @@ const GeoFeatureCollection = Vue.component("GeoFeatureCollection", {
                           ),
                 })
                     .on("click", onClick)
-                    .bindTooltip(feature.properties.title, {
+                    .bindTooltip(tooltipTitle, {
                         className: "geo-feature-collection-tooltip",
                         direction: "top",
                         offset: [0, -64],
@@ -573,14 +575,17 @@ const GeoFeatureCollection = Vue.component("GeoFeatureCollection", {
          */
         setMuted(featureCollection, muted) {
             featureCollection.properties.muted = muted;
-            // Update muted flag on category this featureCollection belongs to.
-            // Category is muted when all featureCollections in it are muted.
-            featureCollection.properties.categoryObj.muted = featureCollection
-                .properties
-                .categoryObj
-                .featureCollections
-                .map(featureCollection => featureCollection.properties.muted)
-                .reduce((a, b) => a && b, true);
+
+            if (featureCollection.properties.categoryObj) {
+                // Update muted flag on category this featureCollection belongs to.
+                // Category is muted when all featureCollections in it are muted.
+                featureCollection.properties.categoryObj.muted = featureCollection
+                    .properties
+                    .categoryObj
+                    .featureCollections
+                    .map(featureCollection => featureCollection.properties.muted)
+                    .reduce((a, b) => a && b, true);
+            }
 
             if (featureCollection.properties.muted) {
                 if (this.featureGroup.hasLayer(featureCollection.properties.geoJSONLayer)) {
@@ -747,7 +752,7 @@ const GeoFeatureCollection = Vue.component("GeoFeatureCollection", {
                                     <button class="text-left leading-tight text-xs flex justify-between w-full items-center space-x-2" :class="{'opacity-50': featureCollection.properties.muted}">
                                         <div @click="toggleSolo(featureCollection)" class="flex items-center space-x-2" style="min-width: 0;">
                                             <span v-if="featureCollection.properties.index" class="rounded-full inline-flex items-center justify-center bg-grey-125 font-bold text-center text-2xs w-4 h-4" style="min-width: 1rem">{{ featureCollection.properties.index }}</span>
-                                            <span class="geo-feature-collection__legend-item">{{ featureCollection.properties.title }}</span>
+                                            <span class="geo-feature-collection__legend-item">{{ featureCollection.properties.collectionTitle }}</span>
                                         </div>
                                         <i @click="setMuted(featureCollection, !featureCollection.properties.muted)" class="text-xs" :class="{'ico--eye': !featureCollection.properties.muted, 'ico--eye-off': featureCollection.properties.muted}"></i>
                                     </button>
@@ -773,13 +778,14 @@ const GeoFeatureCollection = Vue.component("GeoFeatureCollection", {
                                     </div>
                                     <div class="card-headline flex items-center mb-2">
                                         <span v-if="!currentItem.image && currentItem.index" class="rounded-full inline-flex items-center justify-center bg-grey-125 font-bold text-center text-sm w-6 h-6 mr-2">{{ currentItem.index }}</span>
-                                        <span class="flex-1">{{ currentItem.title }}</span>
+                                        <span class="flex-1" v-if="currentItem.collectionTitle">{{ currentItem.collectionTitle }}</span>
+                                        <span class="flex-1" v-else>{{ currentItem.title }}</span>
                                     </div>
 
                                     <div class="card-body-text space-y-4">
                                         <div v-if="currentItem.collectionDescription">{{ currentItem.collectionDescription }}</div>
-                                        <div v-if="currentItem.selfTitle && currentItem.description">
-                                            <h2 class="head-allcaps-4xs">{{ currentItem.selfTitle }}</h2>
+                                        <div v-if="currentItem.title && currentItem.description">
+                                            <h2 class="head-allcaps-4xs">{{ currentItem.title }}</h2>
                                             <div v-if="currentItem.description">{{ currentItem.description }}</div>
                                         </div>
                                     </div>
-- 
GitLab