diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f86ceac..4b2179d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +# 0.16.0 - 2024-10-19 + +### Added + +- User can now select between "Raw" and "Simplified" mode in the map controls. "Simplified" mode will show less points, improving the map performance. "Raw" mode will show all points. + # 0.15.7 - 2024-10-19 ### Fixed diff --git a/app/javascript/controllers/maps_controller.js b/app/javascript/controllers/maps_controller.js index bdbb45b9..44f0e74c 100644 --- a/app/javascript/controllers/maps_controller.js +++ b/app/javascript/controllers/maps_controller.js @@ -10,6 +10,8 @@ import { updatePolylinesOpacity } from "../maps/polylines"; import { fetchAndDrawAreas } from "../maps/areas"; import { handleAreaCreated } from "../maps/areas"; +import { showFlashMessage } from "../maps/helpers"; + import { osmMapLayer } from "../maps/layers"; import { osmHotMapLayer } from "../maps/layers"; import { OPNVMapLayer } from "../maps/layers"; @@ -19,6 +21,7 @@ import { esriWorldStreetMapLayer } from "../maps/layers"; import { esriWorldTopoMapLayer } from "../maps/layers"; import { esriWorldImageryMapLayer } from "../maps/layers"; import { esriWorldGrayCanvasMapLayer } from "../maps/layers"; + import "leaflet-draw"; export default class extends Controller { @@ -193,9 +196,9 @@ export default class extends Controller { .then((response) => response.json()) .then((data) => { if (data.status === 'success') { - this.showFlashMessage('notice', `Preferred map layer updated to: ${selectedLayerName}`); + showFlashMessage('notice', `Preferred map layer updated to: ${selectedLayerName}`); } else { - this.showFlashMessage('error', data.message); + showFlashMessage('error', data.message); } }); } @@ -466,74 +469,14 @@ export default class extends Controller { .then((response) => response.json()) .then((data) => { if (data.status === 'success') { - this.showFlashMessage('notice', data.message); + showFlashMessage('notice', data.message); this.updateMapWithNewSettings(data.settings); } else { - this.showFlashMessage('error', data.message); + showFlashMessage('error', data.message); } }); } - showFlashMessage(type, message) { - // Create the outer flash container div - const flashDiv = document.createElement('div'); - flashDiv.setAttribute('data-controller', 'removals'); - flashDiv.className = `flex items-center fixed top-5 right-5 ${this.classesForFlash(type)} py-3 px-5 rounded-lg`; - - // Create the message div - const messageDiv = document.createElement('div'); - messageDiv.className = 'mr-4'; - messageDiv.innerText = message; - - // Create the close button - const closeButton = document.createElement('button'); - closeButton.setAttribute('type', 'button'); - closeButton.setAttribute('data-action', 'click->removals#remove'); - - // Create the SVG icon for the close button - const closeIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); - closeIcon.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); - closeIcon.setAttribute('class', 'h-6 w-6'); - closeIcon.setAttribute('fill', 'none'); - closeIcon.setAttribute('viewBox', '0 0 24 24'); - closeIcon.setAttribute('stroke', 'currentColor'); - - const closeIconPath = document.createElementNS('http://www.w3.org/2000/svg', 'path'); - closeIconPath.setAttribute('stroke-linecap', 'round'); - closeIconPath.setAttribute('stroke-linejoin', 'round'); - closeIconPath.setAttribute('stroke-width', '2'); - closeIconPath.setAttribute('d', 'M6 18L18 6M6 6l12 12'); - - // Append the path to the SVG - closeIcon.appendChild(closeIconPath); - // Append the SVG to the close button - closeButton.appendChild(closeIcon); - - // Append the message and close button to the flash div - flashDiv.appendChild(messageDiv); - flashDiv.appendChild(closeButton); - - // Append the flash message to the body or a specific flash container - document.body.appendChild(flashDiv); - - // Optional: Automatically remove the flash message after 5 seconds - setTimeout(() => { - flashDiv.remove(); - }, 5000); - } - - // Helper function to get flash classes based on type - classesForFlash(type) { - switch (type) { - case 'error': - return 'bg-red-100 text-red-700 border-red-300'; - case 'notice': - return 'bg-blue-100 text-blue-700 border-blue-300'; - default: - return 'bg-blue-100 text-blue-700 border-blue-300'; - } - } - updateMapWithNewSettings(newSettings) { const currentLayerStates = this.getLayerControlStates(); @@ -647,7 +590,6 @@ export default class extends Controller { return undefined; // Indicate no matching layer name found } - applyLayerControlStates(states) { const layerControl = { Points: this.markersLayer, diff --git a/app/javascript/maps/helpers.js b/app/javascript/maps/helpers.js index f2f310f2..784edff8 100644 --- a/app/javascript/maps/helpers.js +++ b/app/javascript/maps/helpers.js @@ -77,3 +77,62 @@ export function haversineDistance(lat1, lon1, lat2, lon2, unit = 'km') { return R_km * c; // Distance in kilometers } } + +export function showFlashMessage(type, message) { + // Create the outer flash container div + const flashDiv = document.createElement('div'); + flashDiv.setAttribute('data-controller', 'removals'); + flashDiv.className = `flex items-center fixed top-5 right-5 ${classesForFlash(type)} py-3 px-5 rounded-lg`; + + // Create the message div + const messageDiv = document.createElement('div'); + messageDiv.className = 'mr-4'; + messageDiv.innerText = message; + + // Create the close button + const closeButton = document.createElement('button'); + closeButton.setAttribute('type', 'button'); + closeButton.setAttribute('data-action', 'click->removals#remove'); + + // Create the SVG icon for the close button + const closeIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + closeIcon.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + closeIcon.setAttribute('class', 'h-6 w-6'); + closeIcon.setAttribute('fill', 'none'); + closeIcon.setAttribute('viewBox', '0 0 24 24'); + closeIcon.setAttribute('stroke', 'currentColor'); + + const closeIconPath = document.createElementNS('http://www.w3.org/2000/svg', 'path'); + closeIconPath.setAttribute('stroke-linecap', 'round'); + closeIconPath.setAttribute('stroke-linejoin', 'round'); + closeIconPath.setAttribute('stroke-width', '2'); + closeIconPath.setAttribute('d', 'M6 18L18 6M6 6l12 12'); + + // Append the path to the SVG + closeIcon.appendChild(closeIconPath); + // Append the SVG to the close button + closeButton.appendChild(closeIcon); + + // Append the message and close button to the flash div + flashDiv.appendChild(messageDiv); + flashDiv.appendChild(closeButton); + + // Append the flash message to the body or a specific flash container + document.body.appendChild(flashDiv); + + // Optional: Automatically remove the flash message after 5 seconds + setTimeout(() => { + flashDiv.remove(); + }, 5000); +} + +function classesForFlash(type) { + switch (type) { + case 'error': + return 'bg-red-100 text-red-700 border-red-300'; + case 'notice': + return 'bg-blue-100 text-blue-700 border-blue-300'; + default: + return 'bg-blue-100 text-blue-700 border-blue-300'; + } +}