<template> <div class="basemaps-items ui accordion styled"> <div :class="['basemap-item title', { active }]" @click="$emit('activateGroup', basemap.id)" > <i class="map outline fitted icon" aria-hidden="true" /> <span>{{ basemap.title }}</span> </div> <div v-if="queryableLayersOptions.length > 0 && active" :id="`queryable-layers-selector-${basemap.id}`" > <strong>Couche requĂȘtable</strong> <Dropdown :options="queryableLayersOptions" :selected="selectedQueryLayer" :search="true" @update:selection="onQueryLayerChange($event)" /> </div> <div :id="`list-${basemap.id}`" :class="['content', { active }]" :data-basemap-index="basemap.id" > <div v-for="(layer, index) in basemap.layers" :key="basemap.id + '-' + layer.id + '-' + index" class="layer-item transition visible item list-group-item" :data-id="layer.id" > <!-- layer id is used for retrieving layer when changing order --> <p class="layer-handle-sort"> <i class="th icon" aria-hidden="true" /> {{ layer.title }} </p> <label>OpacitĂ© <span>(%)</span></label> <div class="range-container"> <input type="range" min="0" max="1" :value="layer.opacity" step="0.01" @change="updateOpacity($event, layer)" ><output class="range-output-bubble">{{ getOpacity(layer.opacity) }}</output> </div> <div class="ui divider" /> </div> </div> </div> </template> <script> import Sortable from 'sortablejs'; import Dropdown from '@/components/Dropdown.vue'; import mapService from '@/services/map-service'; export default { name: 'LayerSelector', components: { Dropdown, }, props: { basemap: { type: Object, default: null, }, baseMaps: { type: Array, default: () => [], }, active: { type: Boolean, default: false, }, }, data() { return { baseMap: {}, selectedQueryLayer: null, sortable: null, }; }, computed: { queryableLayersOptions() { const queryableLayers = this.basemap.layers.filter((l) => l.queryable === true); return queryableLayers.map((x) => { return { name: x.title, value: x, }; }); } }, mounted() { if (this.queryableLayersOptions.length > 0) { this.selectedQueryLayer = this.queryableLayersOptions[0].name; } setTimeout(this.initSortable.bind(this), 1000); }, methods: { isQueryable(baseMap) { const queryableLayer = baseMap.layers.filter((l) => l.queryable === true); return queryableLayer.length > 0; }, initSortable() { const element = document.getElementById(`list-${this.basemap.id}`); if (element) { this.sortable = new Sortable(element, { animation: 150, handle: '.layer-handle-sort', // The element that is active to drag ghostClass: 'blue-background-class', dragClass: 'white-opacity-background-class', onEnd: () => this.$emit('onlayerMove'), }); } else { console.error(`list-${this.basemap.id} not found in dom`); } }, onQueryLayerChange(layer) { this.selectedQueryLayer = layer.name; const baseMap = this.baseMaps[0].layers.find((l) => l.title === layer.name); if (baseMap) { baseMap.query = true; } else { console.error('No such param \'query\' found among basemap[0].layers'); } layer.query = true; }, getOpacity(opacity) { return Math.round(parseFloat(opacity) * 100); }, updateOpacity(event, layer) { mapService.updateOpacity(layer.id, event.target.value); layer.opacity = event.target.value; }, } }; </script> <style> .basemap-item.title > i { margin-left: -1em !important; } .basemap-item.title > span { margin-left: .5em; } .queryable-layers-dropdown { margin-bottom: 1em; } .queryable-layers-dropdown > label { font-weight: bold; } </style>