<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="setQueryLayer($event)" /> </div> <div :id="`list-${basemap.id}`" :class="['content', { active }]" :data-basemap-index="basemap.id" > <div v-for="layer in basemap.layers" :key="basemap.id + '-' + layer.id + Math.random()" 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, }, active: { type: Boolean, default: false, }, selectedQueryLayer: { type: String, default: '' } }, data() { return { 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() { 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`); } }, setQueryLayer(layer) { this.$emit('onQueryLayerChange', layer.name); }, getOpacity(opacity) { return Math.round(parseFloat(opacity) * 100); }, updateOpacity(event, layer) { const layerId = layer.id; const opacity = event.target.value; mapService.updateOpacity(layerId, opacity); this.$emit('onOpacityUpdate', { layerId, opacity }); }, } }; </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>