// = require decidim/map // = require leaflet.featuregroup.subgroup // = require decidim/decidim_awesome/awesome_map/categories // = require decidim/decidim_awesome/awesome_map/proposals // = require decidim/decidim_awesome/awesome_map/meetings // = require_self ((exports) => { const { fetchProposals, fetchMeetings, getCategory } = exports.AwesomeMap; const collapsedMenu = $("#map").data("collapsed"); const components = $("#map").data("components"); const popupMeetingTemplateId = "marker-meeting-popup"; const popupProposalTemplateId = "marker-proposal-popup"; const cluster = L.markerClusterGroup(); const amendments = []; const layers = {}; const control = L.control.layers(null, null, { position: 'topleft', sortLayers: false, collapsed: collapsedMenu, // hideSingleBase: true }); const allMarkers = []; const drawMarker = (element, marker, component) => { let tmpl = component.type === "proposals" ? popupProposalTemplateId : popupMeetingTemplateId, node = document.createElement("div"); $.tmpl($(`#${tmpl}`), element).appendTo(node); marker.bindPopup(node, { maxwidth: 640, minWidth: 500, keepInView: true, className: "map-info" }).openPopup(); allMarkers.push({ marker: marker, component: component, element: element }); // Check if it has amendments, add it to a list if(element.amendments && element.amendments.length) { element.amendments.forEach((amendment) => { amendments.push(amendment.emendation.id); }); } // Add to category layer let cat = getCategory(element.category); if(layers[cat.id]) { marker.addTo(layers[cat.id].group); // show category if hidden const $label = $(`.awesome_map-category_${cat.id}`).closest("label"); const $parent = $(`.awesome_map-category_${cat.parent}`).closest("label"); $label.show(); // update number of items $label.attr("title", parseInt($label.attr("title") || 0) + 1); // show parent if apply $parent.show(); $parent.attr("title", parseInt($parent.attr("title") || 0) + 1); // update component stats const $component = $(`#awesome_map-component-${component.id}`); $component.attr("title", parseInt($component.attr("title") || 0) + 1); } return marker; }; const loadElements = (map) => { // legends control.addTo(map); cluster.addTo(map); // Load markers components.forEach((component) => { if(component.type == "proposals") { // add control layer for proposals layers.proposals = { label: `${component.name || window.DecidimAwesome.texts.proposals}`, group: L.featureGroup.subGroup(cluster) }; control.addOverlay(layers.proposals.group, layers.proposals.label); layers.proposals.group.addTo(map); // add control layer for amendments if any if(component.amendments) { layers.amendments = { label: `${window.DecidimAwesome.texts.amendments}`, group: L.featureGroup.subGroup(cluster) } control.addOverlay(layers.amendments.group, layers.amendments.label); layers.amendments.group.addTo(map); } fetchProposals(component, '', (element, marker) => { drawMarker(element, marker, component).addTo(layers.proposals.group); }, () => { // finall call map.fitBounds(cluster.getBounds(), { padding: [50, 50] }); allMarkers.forEach((item) => { // add marker to amendments layers if it's an amendment if(amendments.find((a) => a == item.element.id)) { item.marker.removeFrom(layers.proposals.group); item.marker.addTo(layers.amendments.group); } }); }); } if(component.type == "meetings") { // add control layer for meetings layers.meetings = { label: `${component.name || window.DecidimAwesome.texts.meetings}`, group: L.featureGroup.subGroup(cluster) }; control.addOverlay(layers.meetings.group, layers.meetings.label); layers.meetings.group.addTo(map); fetchMeetings(component, '', (element, marker) => { drawMarker(element, marker, component).addTo(layers.meetings.group); }, () => { map.fitBounds(cluster.getBounds(), { padding: [50, 50] }); }); } }); // add categories control layers if(window.AwesomeMap.categories.length) { let lastLayer = layers[Object.keys(layers)[Object.keys(layers).length - 1]]; // Add Categories "title" if(lastLayer) { lastLayer.label = `${lastLayer.label}
${window.DecidimAwesome.texts.categories}`; control.removeLayer(lastLayer.group); control.addOverlay(lastLayer.group, lastLayer.label); } window.AwesomeMap.categories.forEach((category) => { // add control layer for this category layers[category.id] = { label: ` ${category.name}`, group: L.featureGroup.subGroup(cluster) }; layers[category.id].group.addTo(map); control.addOverlay(layers[category.id].group, layers[category.id].label); // hide layer by default, it will be activated if there's any marker in it setTimeout(() => { $(`.awesome_map-category_${category.id}`).closest("label").hide(); }); }); // watch events for subcategories syncronitzation const getCatFromClass = (name) => { let id = name.match(/awesome_map-category_(\d+)/) if(!id) return; const cat = getCategory(id[1]); if(!cat || !cat.name) return; return cat; }; const indeterminateInput = (id) => { $('[class^="awesome_map-category_"]').parent().prev().prop("indeterminate", false); if(id) { let $input = $(`.awesome_map-category_${id}`).parent().prev(); if(!$input.prop("checked")) { $input.prop("indeterminate", true); } } }; map.on('overlayadd', (e) => { const cat = getCatFromClass(e.name); if(!cat) return; // if it's a children, put the parent to indeterminate indeterminateInput(cat.parent); }); // on remove a parent category, remove all children map.on('overlayremove', (e) => { const cat = getCatFromClass(e.name); if(!cat) return; cat.children().forEach((c) => { let $el = $(`.awesome_map-category_${c.id}`); if($el.parent().prev().prop("checked")) { $el.click(); } }); }); } }; // currentMap might not be loaded yet so let's delay a bit // TODO: improve this const waitMap = () => { if(exports.Decidim && exports.Decidim.currentMap) { loadElements(exports.Decidim.currentMap); } else { setTimeout(() => { waitMap(); }, 100); } }; waitMap(); })(window);