175 lines
5.4 KiB
JavaScript
175 lines
5.4 KiB
JavaScript
import { Controller } from "@hotwired/stimulus";
|
|
import { GisState } from "../state.js";
|
|
import UI from "../ui.js";
|
|
import { INIT_ZOOM } from "../gis.js";
|
|
|
|
const html = String.raw;
|
|
|
|
export default class extends Controller {
|
|
static targets = [
|
|
'search',
|
|
'results',
|
|
'clear',
|
|
'container',
|
|
'category',
|
|
'technique',
|
|
];
|
|
|
|
disableTechnique() {
|
|
this.techniqueTarget.disabled = true;
|
|
}
|
|
disableCategory() {
|
|
this.categoryTarget.disabled = true;
|
|
}
|
|
/**
|
|
*
|
|
* @param {Event} event
|
|
*/
|
|
async submitSearch(event) {
|
|
event.preventDefault();
|
|
// Re-enable disabled filters, if any
|
|
this.categoryTarget.disabled = false;
|
|
this.techniqueTarget.disabled = false;
|
|
const data = new FormData(event.target);
|
|
const body = {};
|
|
const map = GisState.map;
|
|
const techs = GisState.layers.buildingTechs;
|
|
const techsMarkers = GisState.markers.buildingTechs;
|
|
|
|
// Reset search for building techs...
|
|
for (const key of Object.keys(techsMarkers)) {
|
|
map.removeLayer(techsMarkers[key]);
|
|
}
|
|
|
|
for (const entry of data.entries()) {
|
|
body[entry[0]] = entry[1];
|
|
}
|
|
|
|
const response = await fetch(`${GisState.apiUrl}/search?` + new URLSearchParams(body));
|
|
const results = await response.json();
|
|
|
|
this.containerTarget.classList.remove('is-hidden');
|
|
if (results.count) {
|
|
this.#injectResults(results);
|
|
// Reset zoom level after successful search
|
|
map.setZoom(INIT_ZOOM);
|
|
this.#filterMap(results);
|
|
|
|
// Should technique always be shown after a search?
|
|
for (const key of Object.keys(techsMarkers)) {
|
|
for (const record of results.sites) {
|
|
// Adjust for non-site records!!
|
|
if (techsMarkers[key].options.site === record.label
|
|
&& techsMarkers[key].options.label === body.technique)
|
|
map.addLayer(techsMarkers[key]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
clearSearch() {
|
|
this.categoryTarget.disabled = false;
|
|
this.techniqueTarget.disabled = false;
|
|
const map = GisState.map;
|
|
|
|
// Restore layer groups in map
|
|
for (const key of Object.keys(GisState.layers)) {
|
|
map.addLayer(GisState.layers[key]);
|
|
}
|
|
|
|
// Empty result set
|
|
this.resultsTarget.innerHTML = '';
|
|
this.containerTarget.classList.add('is-hidden');
|
|
// Reset map zoom
|
|
map.setZoom(INIT_ZOOM);
|
|
}
|
|
|
|
#injectResults(results) {
|
|
/**
|
|
* @type {HTMLOutputElement} output
|
|
*/
|
|
const output = this.resultsTarget;
|
|
output.innerHTML = '';
|
|
|
|
if (results.count === 0) {
|
|
output.innerHTML = html`
|
|
<p class="has-background-white-bis p-4 mt-0 has-text-centered">
|
|
Nessun risultato trovato per i parametri di ricerca
|
|
</p>
|
|
`;
|
|
}
|
|
|
|
delete results.count;
|
|
|
|
for (const group of Object.keys(results)) {
|
|
if (results[group].length) this.#populateResults(group, results[group], output);
|
|
}
|
|
}
|
|
/**
|
|
*
|
|
* @param {string} group
|
|
* @param {Array<Object>} resultGroup
|
|
* @param {HTMLOutputElement} output
|
|
*/
|
|
#populateResults(group, resultGroup, output) {
|
|
const markers = GisState.markers[group];
|
|
for (const result of resultGroup) {
|
|
let coordinates = '';
|
|
for (let key of Object.keys(markers)) {
|
|
if (markers[key].options.data.label === result.label) {
|
|
coordinates = key;
|
|
}
|
|
}
|
|
|
|
// TODO The group value should be dynamic!!
|
|
const item = html`
|
|
<tr>
|
|
<td class="pt-4">${result.label}</td>
|
|
<td>
|
|
<button class="button is-link"
|
|
data-controller="marker"
|
|
data-action="marker#go"
|
|
data-marker-zoom-param="17"
|
|
data-marker-coords-value="${coordinates}"
|
|
data-marker-group-value="${resultGroup}">
|
|
Vai
|
|
<span class="ml-1 icon">
|
|
<i class="fa fa-chevron-right"></i>
|
|
</span>
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
`;
|
|
|
|
output.innerHTML += item;
|
|
}
|
|
}
|
|
/**
|
|
*
|
|
* @param {Object} results
|
|
*/
|
|
#filterMap(results) {
|
|
const map = GisState.map;
|
|
|
|
// Remove all layer groups first
|
|
for (const key of Object.keys(GisState.layers)) {
|
|
map.removeLayer(GisState.layers[key]);
|
|
}
|
|
|
|
const markers = GisState.markers;
|
|
|
|
for (let group of Object.keys(results)) {
|
|
for (let key of Object.keys(markers[group])) {
|
|
// If map has layers from previous search results...
|
|
map.removeLayer(markers[group][key]);
|
|
|
|
for (const result of results[group]) {
|
|
if (markers[group][key].options.data.label === result.label) {
|
|
map.addLayer(markers[group][key]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|