243 lines
7.5 KiB
JavaScript
243 lines
7.5 KiB
JavaScript
'use strict';
|
|
|
|
import Spotlight from './vendor/spotlight.js/src/js/spotlight.js';
|
|
import { SiteSheet } from './components/SiteSheet.js';
|
|
import { SiteDocuments } from './components/SiteDocuments.js';
|
|
import { SiteSurveys } from './components/SiteSurveys.js';
|
|
import { SitePhotos } from './components/SitePhotos.js';
|
|
import { NotConservedSheet } from './components/NotConservedSheet.js';
|
|
import GIS from './gis.js';
|
|
|
|
/**
|
|
* @namespace UI
|
|
*/
|
|
const UI = {};
|
|
|
|
/**
|
|
* Add a Leaflet control to center the map
|
|
* @param {Map} map The Leaflet map object
|
|
* @param {LatLngExpression} centerCoords The coordinates to center the map
|
|
* @param {number} zoom Zoom level
|
|
*/
|
|
UI.addCenterMapControl = function (map, centerCoords, zoom) {
|
|
L.Control.CenterControl = L.Control.extend({
|
|
options: {
|
|
position: 'topleft'
|
|
},
|
|
onAdd: function (map) {
|
|
let controlDiv = L.DomUtil.create('div', 'leaflet-draw-toolbar leaflet-bar');
|
|
L.DomEvent
|
|
.addListener(controlDiv, 'click', L.DomEvent.stopPropagation)
|
|
.addListener(controlDiv, 'click', L.DomEvent.preventDefault)
|
|
.addListener(controlDiv, 'click', function () {
|
|
map.setView(centerCoords, zoom, {animate: true});
|
|
}
|
|
);
|
|
let controlUI = L.DomUtil.create('a', 'leaflet-draw-edit-remove', controlDiv);
|
|
controlUI.title = 'Centra la mappa';
|
|
controlUI.href = '#';
|
|
controlUI.innerHTML = `
|
|
<span class="icon is-medium">
|
|
<i class="fas fa-lg fa-crosshairs"></i>
|
|
</span>
|
|
`;
|
|
return controlDiv;
|
|
}
|
|
});
|
|
|
|
let centerCtr = new L.Control.CenterControl();
|
|
map.addControl(centerCtr);
|
|
}
|
|
/**
|
|
* Toggle burger menu for small screens
|
|
* @param {string} burgerClass The CSS class of the burger element
|
|
*/
|
|
UI.toggleBurger = function(burgerClass) {
|
|
const burger = document.querySelector(`.${burgerClass}`);
|
|
burger.addEventListener('click', () => {
|
|
burger.classList.toggle('is-active');
|
|
const menuId = burger.getAttribute('data-target');
|
|
document.querySelector(`#${menuId}`).classList.toggle('is-active');
|
|
});
|
|
}
|
|
/**
|
|
* Toggle side menu and rescale map container
|
|
* @param {string} triggerId The ID of the trigger element
|
|
*/
|
|
UI.toggleMenu = function (triggerId) {
|
|
const trigger = document.querySelector(`#${triggerId}`);
|
|
trigger.addEventListener('click', () => {
|
|
const menu = document.querySelector('#menu');
|
|
menu.classList.toggle('is-hidden');
|
|
menu.classList.toggle('is-3');
|
|
//document.querySelector('#map').parentElement.classList.toggle('is-full');
|
|
});
|
|
}
|
|
/**
|
|
* Open a modal with DB site data
|
|
* @todo Refactor!!! Web components??
|
|
* @param {object} data The data retrieved from the DB to display as modal content
|
|
* @param {string} selector The modal selector
|
|
*/
|
|
UI.openSiteModal = async function (data, selector) {
|
|
const modal = document.querySelector(selector);
|
|
const tabs = modal.querySelector('.tabs > ul');
|
|
let dataTabs = modal.querySelectorAll('.data-tabs');
|
|
|
|
// Reset data tabs content
|
|
for (let tab of dataTabs) {
|
|
tab.innerHTML = '';
|
|
}
|
|
//tabs.classList.remove('is-hidden');
|
|
|
|
let siteSheet = new SiteSheet();
|
|
siteSheet.siteData = data;
|
|
|
|
modal.querySelector('#short-sheet').innerHTML = siteSheet.renderShort();
|
|
if (data.description) {
|
|
modal.querySelector('#site-sheet').innerHTML = siteSheet.render();
|
|
}
|
|
|
|
let images = modal.querySelector('#photos');
|
|
|
|
if (data.documents?.length) {
|
|
let siteDocs = new SiteDocuments;
|
|
siteDocs.siteData = data;
|
|
modal.querySelector('#documents').innerHTML = siteDocs.render();
|
|
}
|
|
|
|
let surveys = data.images.filter(i => i.type === 'Survey');
|
|
let photos = data.images.filter(i => i.type === 'Photo');
|
|
|
|
if (images.innerHTML.length === 0) {
|
|
let siteSurveys = new SiteSurveys;
|
|
siteSurveys.siteData = surveys[0] ?? undefined;
|
|
images.innerHTML += surveys[0] ? siteSurveys.render() : '';
|
|
|
|
let sitePhotos = new SitePhotos;
|
|
sitePhotos.siteData = photos[0] ?? undefined;
|
|
images.innerHTML += photos[0] ? sitePhotos.render() : '';
|
|
}
|
|
|
|
// Move to Stimulus?
|
|
// TODO Awful!!!
|
|
tabs.childNodes.forEach(node => {
|
|
if (node.nodeName === 'LI') {
|
|
node.addEventListener('click', () => {
|
|
node.classList.add('is-active');
|
|
|
|
for (let el of tabs.childNodes) {
|
|
if (el.nodeName === 'LI' && el !== node) {
|
|
el.classList.remove('is-active');
|
|
}
|
|
}
|
|
|
|
for (let tab of dataTabs) {
|
|
tab.classList.add('is-hidden');
|
|
if (tab.id == node.id.replace('for-','')) {
|
|
tab.classList.remove('is-hidden');
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
modal.classList.add('is-active');
|
|
const closeBtn = modal.querySelector('.modal-close');
|
|
const modalBg = modal.querySelector('.modal-background');
|
|
const closeModal = () => modal.classList.remove('is-active');
|
|
// CLose modal when clicking either on the X button or on the background
|
|
closeBtn.addEventListener('click', () => closeModal());
|
|
modalBg.addEventListener('click', () => closeModal());
|
|
|
|
this.imageGallery('gallery-1', surveys);
|
|
this.imageGallery('gallery-2', photos);
|
|
}
|
|
/**
|
|
* @param {object} data The data retrieved from the DB to display as modal content
|
|
* @param {string} selector The modal selector
|
|
*/
|
|
UI.openNotConserModal = async function (data, selector) {
|
|
const modal = document.querySelector(selector);
|
|
|
|
let sheet = new NotConservedSheet();
|
|
sheet.siteData = data;
|
|
modal.querySelector('#not-conser-sheet').innerHTML = await sheet.render();
|
|
modal.addEventListener('click', event => {
|
|
const biblio = document.querySelector('#biblio');
|
|
if (event.target.id.includes('cit')) {
|
|
|
|
// DEBUG
|
|
console.log(event.target.id);
|
|
|
|
const id = event.target.id.replace('cit-','');
|
|
|
|
biblio.innerHTML = '<button class="delete"></button>';
|
|
biblio.innerHTML += sheet.getReference(id);
|
|
biblio.classList.remove('is-hidden');
|
|
biblio.scrollIntoView({behavior: 'smooth'});
|
|
}
|
|
|
|
if (event.target.className == 'delete') {
|
|
biblio.classList.add('is-hidden');
|
|
}
|
|
});
|
|
|
|
modal.classList.add('is-active');
|
|
const closeBtn = modal.querySelector('.modal-close');
|
|
const modalBg = modal.querySelector('.modal-background');
|
|
const closeModal = () => modal.classList.remove('is-active');
|
|
// CLose modal when clicking either on the X button or on the background
|
|
closeBtn.addEventListener('click', () => closeModal());
|
|
modalBg.addEventListener('click', () => closeModal());
|
|
|
|
}
|
|
/**
|
|
* @param {string} menuListSel Menu list selector
|
|
* @param {L.Map} map
|
|
* @param {L.LayerGroup} sites
|
|
*/
|
|
UI.sitesMenu = function (menuListSel, map, sites) {
|
|
// Close menu if arrow button is clicked...
|
|
this.toggleMenu('close-menu');
|
|
|
|
const menu = document.querySelector(menuListSel);
|
|
menu.addEventListener('click', async event => {
|
|
if (event.target.nodeName === 'A') {
|
|
const layerId = event.target.id;
|
|
// zoom to layer...
|
|
const layer = sites.customGetLayer(layerId);
|
|
const data = await GIS.layerData(layerId);
|
|
map.setView(
|
|
layer.getBounds().getCenter(),
|
|
19,
|
|
{animate: true, duration: 1, easeLinearity: 0.25}
|
|
);
|
|
setTimeout(
|
|
() => this.openSiteModal(data, '#site-data'),
|
|
1200
|
|
);
|
|
}
|
|
});
|
|
}
|
|
/**
|
|
* Open Spotlight gallery
|
|
* @param {string} galleryId The id of the trigger element
|
|
* @param {Array<Object>} images Array of image objects from DB
|
|
*/
|
|
UI.imageGallery = function (galleryId, images) {
|
|
const element = document.querySelector(`#${galleryId}`);
|
|
|
|
if (element) {
|
|
let gallery = [];
|
|
for (let img of images) {
|
|
gallery.push({src: `img/${img.filename}`, description: img.caption});
|
|
}
|
|
|
|
document.querySelector(`#${galleryId}`).addEventListener('click', () => {
|
|
Spotlight.show(gallery);
|
|
});
|
|
}
|
|
}
|
|
|
|
export default UI; |