<template> <div class="ui segment"> <div class="field required"> <label for="basemap-title">Titre</label> <input v-model="basemap.title" 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}`" v-if="basemap.layers" class="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 @click="addLayer" class="ui compact small icon left floated button green" > <i class="ui plus icon"></i> <span>Ajouter une couche</span> </a> </div> <div @click="deleteBasemap" class="ui buttons"> <a class=" ui compact red small icon right floated button button-hover-green " > <i class="ui trash alternate icon"></i> <span>Supprimer ce fond cartographique</span> </a> </div> </div> </div> </template> <script> import Sortable from "sortablejs"; import ProjectMappingContextLayer from "@/components/project/ProjectMappingContextLayer.vue"; export default { name: "Project_mapping_basemap", props: ["basemap"], components: { ProjectMappingContextLayer, }, computed: { maxLayersCount: function () { return this.basemap.layers.reduce((acc, curr) => { if (curr.dataKey > acc) { return curr.dataKey; } else { return acc; } }, 0); }, }, 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) { this.$store.commit("map/UPDATE_BASEMAP", { id: this.basemap.id, title: evt.title, errors: evt.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), }); }, }, watch: { "basemap.title": { deep: true, handler: function (newValue, oldValue) { if (newValue !== oldValue) { this.basemap.title = newValue; if (newValue === "") this.basemap.errors = "Veuillez compléter ce champ."; else this.basemap.errors = ""; this.updateTitle(this.basemap); } }, }, }, created() { if (this.basemap.layers) { //* add datakeys to layers coming from api this.fillLayersWithDatakey(this.basemap.layers); } }, // destroyed(){ // this.errors = []; // } mounted() { //* not present in original this.initSortable(); // if (!this.basemap.title) { // this.$store.commit("map/UPDATE_BASEMAP", { // id: this.basemap.id, // title: newValue, // }); // } }, }; </script> <style scoped> .button { margin-right: 0.5em !important; } </style>