Skip to content
Snippets Groups Projects
project_mapping_basemap.vue 4.89 KiB
<template>
  <div class="ui segment">
    <div class="field required">
      <label for="basemap-title">Titre</label>
      <!-- eslint-disable -->
      <input
        :value="basemap.title"
        @input="updateTitle"
        type="text"
        name="basemap-title"
        required
      >
      <ul
        v-if="basemap.errors && basemap.errors.length > 0"
        id="errorlist-title"
        class="errorlist"
      >
        <li>
          {{ basemap.errors }}
        </li>
      </ul>
    </div>

    <div class="nested">
      <div
        :id="`list-${basemap.id}`"
        :class="[basemap.layers.length > 0 ? 'ui segments': '', 'layers-container']"
      >
        <ProjectMappingContextLayer
          v-for="layer in basemap.layers"
          :key="'layer-' + layer.dataKey"
          :layer="layer"
          :basemapid="basemap.id"
        />
      </div>
      <div class="ui buttons">
        <a
          class="ui compact small icon left floated button green"
          @click="addLayer"
        >
          <i class="ui plus icon" />
          <span>Ajouter une couche</span>
        </a>
      </div>

      <div
        class="ui buttons"
        @click="deleteBasemap"
      >
        <a
          class="
            ui
            compact
            red
            small
            icon
            right
            floated
            button button-hover-green
          "
        >
          <i class="ui trash alternate icon" />
          <span>Supprimer ce fond cartographique</span>
        </a>
      </div>
    </div>
  </div>
</template>

<script>
/* eslint-disable */

import Sortable from 'sortablejs';
import ProjectMappingContextLayer from '@/components/project/ProjectMappingContextLayer.vue';

export default {
  name: 'ProjectMappingBasemap',

  components: {
    ProjectMappingContextLayer,
  },

  props: {
    basemap: {
      type: Object,
      default: null,
    }
  },

  computed: {
    maxLayersCount: function () {
      return this.basemap.layers.reduce((acc, curr) => {
        if (curr.dataKey > acc) {
          return curr.dataKey;
        } else {
          return acc;
        }
      }, 0);
    },
  },

  created() {
    if (this.basemap.layers) {
      //* add datakeys to layers coming from api
      this.fillLayersWithDatakey(this.basemap.layers);
    }
  },

  mounted() {
    this.initSortable();
  },

  methods: {
    deleteBasemap() {
      this.$store.commit('map/DELETE_BASEMAP', this.basemap.id);
    },

    addLayer(layer) {
      const newLayer = {
        dataKey: this.maxLayersCount + 1,
        opacity: '1.00',
        order: 0,
        queryable: false,
        title: 'Open street map',
        ...layer,
      };
      this.$store.commit('map/UPDATE_BASEMAP', {
        layers: [...this.basemap.layers, newLayer],
        id: this.basemap.id,
        title: this.basemap.title,
        errors: this.basemap.errors,
      });
    },

    updateTitle(evt) {
      let errors = '';
      if(evt.target.value === '') { //* delete or add error message while typing
        errors = "Veuillez compléter ce champ.";
      }
      this.$store.commit('map/UPDATE_BASEMAP', {
        id: this.basemap.id,
        title: evt.target.value,
        errors,
      });



    },

    removeLayer(dataKey) {
      this.layers = this.layers.filter((layer) => layer.dataKey !== dataKey);
    },

    fillLayersWithDatakey(layers) {
      let dataKey = 0;
      this.$store.commit('map/REPLACE_BASEMAP_LAYERS', {
        basemapId: this.basemap.id,
        layers: layers.map((el) => {
          dataKey += 1;
          return { dataKey, ...el };
        }),
      });
    },

    //* drag & drop *//
    onlayerMove() {
      //* Get the names of the current layers in order.
      const currentLayersNamesInOrder = Array.from(
        document.getElementsByClassName('layer-item')
      ).map((el) => el.id);

      //* increment value 'order' in this.basemap.layers looping over layers from template ^
      let order = 0;
      let movedLayers = [];
      for (let id of currentLayersNamesInOrder) {
        let matchingLayer = this.basemap.layers.find(
          (el) => el.dataKey === Number(id)
        );
        if (matchingLayer) {
          matchingLayer['order'] = order;
          movedLayers.push(matchingLayer);
          order += 1;
        }
      }
      //* update the store
      this.$store.commit('map/UPDATE_BASEMAP', {
        layers: movedLayers,
        id: this.basemap.id,
        title: this.basemap.title,
        errors: this.basemap.errors,
      });
    },

    initSortable() {
      new Sortable(document.getElementById(`list-${this.basemap.id}`), {
        animation: 150,
        handle: '.layer-handle-sort', // The element that is active to drag
        ghostClass: 'blue-background-class',
        dragClass: 'white-opacity-background-class',
        onEnd: this.onlayerMove.bind(this),
      });
    },
  },
};
</script>

<style scoped>
.button {
  margin-right: 0.5em !important;
}
</style>