Skip to content
Snippets Groups Projects
LayerSelector.vue 3.84 KiB
Newer Older
<template>
  <div class="basemaps-items ui accordion styled">
    <div
      :class="['basemap-item title', { active }]"
      <i
        class="map outline fitted icon"
        aria-hidden="true"
      />
      <span>{{ basemap.title }}</span>
      v-if="queryableLayersOptions.length > 0 && active"
      :id="`queryable-layers-selector-${basemap.id}`"
    >
      <strong>Couche requêtable</strong>
      <Dropdown
        :selected="selectedQueryLayer"
        :search="true"
        @update:selection="setQueryLayer($event)"
      />
    </div>
    <div
      :id="`list-${basemap.id}`"
      :class="['content', { active }]"
      :data-basemap-index="basemap.id"
    >
      <div
        :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é &nbsp;<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,
    },
    selectedQueryLayer: {
      type: String,
      default: ''
    }
    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 });
.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>