diff --git a/src/components/Dropdown.vue b/src/components/Dropdown.vue
index 797a9782df2038175f37c0e513c4ae7edf5b8369..b63ebe80e5432298cc6b9851b9c2f6e30f37d69a 100644
--- a/src/components/Dropdown.vue
+++ b/src/components/Dropdown.vue
@@ -10,18 +10,18 @@
   >
     <input
       v-if="search"
+      v-model="input"
+      v-on:keyup.enter="select(0)"
+      v-on:keyup.esc="toggleDropdown(false)"
       class="search"
       autocomplete="off"
       tabindex="0"
-      @input="handelInput"
-      v-on:keyup.enter="select(0)"
-      v-model="input"
-      :placeholder="placeholder"
+      :placeholder="placehold"
+      ref="input"
     />
-    <!-- {{placeholder}} -->
-    <div class="default text">{{ selected || placeholder }}</div>
+    <div v-if="!input" class="default text">{{ selected }}</div>
     <i
-      :class="['dropdown icon', { clear: search && selected }]"
+      :class="['dropdown icon', { clear: clearable && selected }]"
       @click="clear"
     ></i>
     <div :class="['menu', { 'visible transition': isOpen }]">
@@ -44,7 +44,14 @@
 export default {
   name: "Dropdown",
 
-  props: ["options", "selected", "disabled", "search", "placeholder"],
+  props: [
+    "options",
+    "selected",
+    "disabled",
+    "search",
+    "placeholder",
+    "clearable",
+  ],
 
   computed: {
     processedOptions: function () {
@@ -57,6 +64,10 @@ export default {
       }
       return options.length > 0 ? options : null;
     },
+
+    placehold() {
+      return this.input ? "" : this.placeholder;
+    },
   },
 
   data() {
@@ -66,44 +77,53 @@ export default {
       identifier: 0,
     };
   },
+
   methods: {
-    toggleDropdown() {
-      this.isOpen = !this.isOpen;
+    toggleDropdown(val) {
+      if (this.isOpen) {
+        this.input = ""; // * clear input field when closing dropdown
+      } else if (this.search) {
+        //* focus on input if is a search dropdown
+        this.$refs.input.focus({
+          preventScroll: true,
+        });
+      } else if (this.clearable && val.target && this.selected) {
+        this.clear(); //* clear selected and input
+      }
+      this.isOpen = typeof val === "boolean" ? val : !this.isOpen;
     },
+
     select(index) {
+      // * toggle dropdown is called several time, timeout delay this function to be the last
       setTimeout(() => {
-        this.isOpen = false; // * quick & dirty, car toggle dropdown est rappelé plusieurs fois aileurs, à creuser...
-      }, 500);
+        this.isOpen = false;
+      }, 0);
       this.$emit("update:selection", this.options[index]);
       this.input = "";
     },
+
     searchOptions(options) {
       return options.filter((el) =>
         el.toLowerCase().includes(this.input.toLowerCase())
       );
     },
+
     clear() {
-      if (this.search) {
+      if (this.clearable) {
         this.input = "";
-        this.clearSelected();
+        this.$emit("update:selection", "");
+        if (this.isOpen) this.toggleDropdown(false);
       }
     },
-    clearSelected() {
-      this.$emit("update:selection", "");
-    },
-    handelInput() {
-      this.isOpen = true;
-      this.clearSelected();
-    },
+
     clickOutsideDropdown(e) {
       if (!e.target.closest(`#custom-dropdown${this.identifier}`))
-        this.isOpen = false;
+        this.toggleDropdown(false);
     },
   },
 
   created() {
-    let randomnum = Math.floor(Math.random() * 10000);
-    this.identifier = randomnum;
+    this.identifier = Math.floor(Math.random() * 10000);
     window.addEventListener("mousedown", this.clickOutsideDropdown);
   },
 
diff --git a/src/components/map-layers/SidebarLayers.vue b/src/components/map-layers/SidebarLayers.vue
index 59cd5d1f1a489d7b76f4efbd8454f9c92d5002ea..8ee1575b5b5e6790735d6d1dca07218175aaf406 100644
--- a/src/components/map-layers/SidebarLayers.vue
+++ b/src/components/map-layers/SidebarLayers.vue
@@ -47,7 +47,6 @@
 
     <div
       v-for="basemap in baseMaps"
-      
       :key="`list-${basemap.id}`"
       class="basemaps-items ui accordion styled"
     >
@@ -58,15 +57,17 @@
       >
         {{ basemap.title }}
       </div>
-      <div :id="`queryable-layers-selector-${basemap.id}`" v-if="isQueryable(basemap)">
+      <div
+        :id="`queryable-layers-selector-${basemap.id}`"
+        v-if="isQueryable(basemap)"
+      >
         <b>Couche requêtable</b>
-        <Dropdown 
+        <Dropdown
           @update:selection="onQueryLayerChange($event)"
           :options="getQueryableLayers(basemap)"
           :selected="selectedQueryLayer"
           :search="true"
         />
-
       </div>
       <div
         :class="{ active: isActive(basemap) }"
@@ -77,7 +78,8 @@
         <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"
+          class="layer-item transition visible item list-group-item"
+          :data-id="layer.id"
         >
           <p class="layer-handle-sort">
             <i class="th icon"></i>{{ layer.title }}
@@ -104,168 +106,201 @@
 </template>
 
 <script>
-import { mapUtil } from "@/assets/js/map-util.js";
+import { mapState } from "vuex";
+import Sortable from "sortablejs";
 import Dropdown from "@/components/Dropdown.vue";
-import Sortable from 'sortablejs';
+import { mapUtil } from "@/assets/js/map-util.js";
 
 export default {
   name: "SidebarLayers",
+
   components: {
     Dropdown,
   },
+
   data() {
     return {
-      selectedQueryLayer:null,
-      activeBasemap:null,
+      selectedQueryLayer: null,
+      activeBasemap: null,
       baseMaps: [],
-      layers: [],
       expanded: false,
     };
   },
+
+  computed: {
+    ...mapState("map", ["availableLayers"]),
+  },
+
   methods: {
     isActive(basemap) {
-      return basemap.active != undefined && basemap.active;
+      return basemap.active !== undefined && basemap.active;
     },
+
     activateGroup(basemap) {
       this.baseMaps.forEach((basemap) => (basemap.active = false));
       basemap.active = true;
-      this.activeBasemap=basemap;
+      this.activeBasemap = basemap;
       basemap.title += " "; //weird!! Force refresh
       this.addLayers(basemap);
 
-      let mapOptions = localStorage.getItem('geocontrib-map-options') || {};
-        mapOptions = mapOptions.length ? JSON.parse(mapOptions) : {};
-      let project=this.$route.params.slug;
-        mapOptions[project] = {
-          ...mapOptions[project],
-          'current-basemap-index': basemap.id
-        };
-        localStorage.setItem('geocontrib-map-options', JSON.stringify(mapOptions));
-
-
+      let mapOptions = localStorage.getItem("geocontrib-map-options") || {};
+      mapOptions = mapOptions.length ? JSON.parse(mapOptions) : {};
+      let project = this.$route.params.slug;
+      mapOptions[project] = {
+        ...mapOptions[project],
+        "current-basemap-index": basemap.id,
+      };
+      localStorage.setItem(
+        "geocontrib-map-options",
+        JSON.stringify(mapOptions)
+      );
     },
+
     updateOpacity(event, layer) {
       console.log(event.target.value, layer);
       mapUtil.updateOpacity(layer.id, event.target.value);
       layer.opacity = event.target.value;
     },
+
     getOpacity(opacity) {
       return Math.round(parseFloat(opacity) * 100);
     },
-    onQueryLayerChange(layer){
+
+    onQueryLayerChange(layer) {
       console.log(layer);
-      this.selectedQueryLayer=layer.name;
+      this.selectedQueryLayer = layer.name;
     },
-    isQueryable(baseMap){
-      let queryableLayer=baseMap.layers.filter(l => l.queryable === true);
-      return queryableLayer.length>0;
+
+    isQueryable(baseMap) {
+      let queryableLayer = baseMap.layers.filter((l) => l.queryable === true);
+      return queryableLayer.length > 0;
     },
-    onlayerMove(event){
-      console.log(event)
-      // Get the names of the current layers in order.
-      const currentLayersNamesInOrder = Array.from(document.getElementsByClassName('layer-item transition visible')).map(el => el.children[0].innerText);
 
+    onlayerMove(event) {
+      console.log(event);
+      // Get the names of the current layers in order.
+      const currentLayersNamesInOrder = Array.from(
+        document.getElementsByClassName("layer-item transition visible")
+      ).map((el) => el.children[0].innerText);
       // Create an array to put the layers in order.
       let movedLayers = [];
-             
+
       for (const layerName of currentLayersNamesInOrder) {
-        movedLayers.push(this.activeBasemap.layers.filter(el => el.title === layerName)[0]);
+        movedLayers.push(
+          this.activeBasemap.layers.filter((el) => el.title === layerName)[0]
+        );
       }
-
       // Remove existing layers undefined
-      movedLayers = movedLayers.filter(function(x) {
+      movedLayers = movedLayers.filter(function (x) {
         return x !== undefined;
       });
-      const eventOrder = new CustomEvent('change-layers-order', {
+      const eventOrder = new CustomEvent("change-layers-order", {
         detail: {
-          layers: movedLayers
-        }
-      })
+          layers: movedLayers,
+        },
+      });
       document.dispatchEvent(eventOrder);
       // Save the basemaps options into the localstorage
-      console.log(this.baseMaps)
-      this.setLocalstorageMapOptions(this.baseMaps)
+      console.log(this.baseMaps);
+      this.setLocalstorageMapOptions(this.baseMaps);
     },
+
     setLocalstorageMapOptions(basemaps) {
-      let mapOptions = localStorage.getItem('geocontrib-map-options') || {};
+      let mapOptions = localStorage.getItem("geocontrib-map-options") || {};
       mapOptions = mapOptions.length ? JSON.parse(mapOptions) : {};
-      let project=this.$route.params.slug;
+      let project = this.$route.params.slug;
       mapOptions[project] = {
         ...mapOptions[project],
-        'basemaps': basemaps
+        basemaps: basemaps,
       };
-      localStorage.setItem('geocontrib-map-options', JSON.stringify(mapOptions));
+      localStorage.setItem(
+        "geocontrib-map-options",
+        JSON.stringify(mapOptions)
+      );
     },
 
-    initSortable(){
+    initSortable() {
       this.baseMaps.forEach((basemap) => {
-         new Sortable(document.getElementById(`list-${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)
-          });
+        new Sortable(document.getElementById(`list-${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),
+        });
       });
     },
-
     // Check if there are changes in the basemaps settings. Changes are detected if:
-  // - one basemap has been added or deleted
-  // - one layer has been added or deleted to a basemap
-  areChangesInBasemaps(basemapFromServer, basemapFromLocalstorage={}) {
-    let isSameBasemaps = false;
-    let isSameLayers = true;
-    let isSameTitles = true;
-
-    // Compare the length and the id values of the basemaps
-    const idBasemapsServer = basemapFromServer.map(b => b.id).sort();
-    const idBasemapsLocalstorage = basemapFromLocalstorage.length ? basemapFromLocalstorage.map(b => b.id).sort() : {};
-    isSameBasemaps = (idBasemapsServer.length === idBasemapsLocalstorage.length
-      && idBasemapsServer.every((value, index) => value === idBasemapsLocalstorage[index]))
-
-    // For each basemap, compare the length and id values of the layers
-    outer_block: {
-      for(let basemapServer of basemapFromServer) {
-        let idLayersServer = basemapServer.layers.map(b => b.id).sort();
-        if (basemapFromLocalstorage.length){
-          for (let basemapLocalstorage of basemapFromLocalstorage) {
-            if (basemapServer.id === basemapLocalstorage.id) {
-              let idLayersLocalstorage = basemapLocalstorage.layers.map(b => b.id).sort();
-              isSameLayers = (idLayersServer.length === idLayersLocalstorage.length
-                && idLayersServer.every((value, index) => value === idLayersLocalstorage[index]));
-              if (!isSameLayers) {
-                break outer_block;
+    // - one basemap has been added or deleted
+    // - one layer has been added or deleted to a basemap
+    areChangesInBasemaps(basemapFromServer, basemapFromLocalstorage = {}) {
+      let isSameBasemaps = false;
+      let isSameLayers = true;
+      let isSameTitles = true;
+      // Compare the length and the id values of the basemaps
+      const idBasemapsServer = basemapFromServer.map((b) => b.id).sort();
+      const idBasemapsLocalstorage = basemapFromLocalstorage.length
+        ? basemapFromLocalstorage.map((b) => b.id).sort()
+        : {};
+      isSameBasemaps =
+        idBasemapsServer.length === idBasemapsLocalstorage.length &&
+        idBasemapsServer.every(
+          (value, index) => value === idBasemapsLocalstorage[index]
+        );
+      // For each basemap, compare the length and id values of the layers
+      outer_block: {
+        for (let basemapServer of basemapFromServer) {
+          let idLayersServer = basemapServer.layers.map((b) => b.id).sort();
+          if (basemapFromLocalstorage.length) {
+            for (let basemapLocalstorage of basemapFromLocalstorage) {
+              if (basemapServer.id === basemapLocalstorage.id) {
+                let idLayersLocalstorage = basemapLocalstorage.layers
+                  .map((b) => b.id)
+                  .sort();
+                isSameLayers =
+                  idLayersServer.length === idLayersLocalstorage.length &&
+                  idLayersServer.every(
+                    (value, index) => value === idLayersLocalstorage[index]
+                  );
+                if (!isSameLayers) {
+                  break outer_block;
+                }
               }
             }
           }
         }
-      }
-
-      // Compare basemaps titles
-      const titlesBasemapsServer = basemapFromServer.map(b => b.title).sort();
-      const titlesBasemapsLocalstorage = basemapFromLocalstorage.length ? basemapFromLocalstorage.map(b => b.title).sort() : {};
+        // Compare basemaps titles
+        const titlesBasemapsServer = basemapFromServer
+          .map((b) => b.title)
+          .sort();
+        const titlesBasemapsLocalstorage = basemapFromLocalstorage.length
+          ? basemapFromLocalstorage.map((b) => b.title).sort()
+          : {};
 
-      isSameTitles = titlesBasemapsServer.every((title, index) => title === titlesBasemapsLocalstorage[index]);
+        isSameTitles = titlesBasemapsServer.every(
+          (title, index) => title === titlesBasemapsLocalstorage[index]
+        );
 
-      if (!isSameTitles) {
-        break outer_block;
+        if (!isSameTitles) {
+          break outer_block;
+        }
       }
-    }
-    return !(isSameBasemaps && isSameLayers && isSameTitles);
-  },
-    getQueryableLayers(baseMap){
-      let queryableLayer=baseMap.layers.filter(l => l.queryable === true);
-      return queryableLayer.map(x=>{
+      return !(isSameBasemaps && isSameLayers && isSameTitles);
+    },
+
+    getQueryableLayers(baseMap) {
+      let queryableLayer = baseMap.layers.filter((l) => l.queryable === true);
+      return queryableLayer.map((x) => {
         return {
-          name:x.title,
-          value:x
-        }
+          name: x.title,
+          value: x,
+        };
       });
     },
+
     addLayers(baseMap) {
-     
       baseMap.layers.forEach((layer) => {
-        var layerOptions = this.layers.find((l) => l.id === layer.id);
+        var layerOptions = this.availableLayers.find((l) => l.id === layer.id);
         console.log(layerOptions);
         layer = Object.assign(layer, layerOptions);
         layer.options.basemapId = baseMap.id;
@@ -276,35 +311,39 @@ export default {
       mapUtil.addLayers(baseMap.layers.slice().reverse(), null, null);
     },
   },
+
   mounted() {
     this.baseMaps = this.$store.state.map.basemaps;
-    let project=this.$route.params.slug;
-    const mapOptions = JSON.parse(localStorage.getItem('geocontrib-map-options')) || {};
-    if (mapOptions 
-        && mapOptions[project]) {
-
-      // If already in the storage, we need to check if the admin did some 
+    let project = this.$route.params.slug;
+    const mapOptions =
+      JSON.parse(localStorage.getItem("geocontrib-map-options")) || {};
+    if (mapOptions && mapOptions[project]) {
+      // If already in the storage, we need to check if the admin did some
       // modification in the basemaps on the server side. The rule is: if one layer has been added
       // or deleted in the server, then we reset the localstorage.
-      const baseMapsFromLocalstorage = mapOptions[project]['basemaps'];
-      const areChanges = this.areChangesInBasemaps(this.baseMaps, baseMapsFromLocalstorage);
+      const baseMapsFromLocalstorage = mapOptions[project]["basemaps"];
+      const areChanges = this.areChangesInBasemaps(
+        this.baseMaps,
+        baseMapsFromLocalstorage
+      );
 
       if (areChanges) {
         mapOptions[project] = {
-          'map-options': this.baseMaps,
-          'current-basemap-index': 0,
+          "map-options": this.baseMaps,
+          "current-basemap-index": 0,
         };
-        localStorage.setItem('geocontrib-map-options', JSON.stringify(mapOptions));
+        localStorage.setItem(
+          "geocontrib-map-options",
+          JSON.stringify(mapOptions)
+        );
       } else {
         this.baseMaps = baseMapsFromLocalstorage;
       }
     }
 
-    
-    this.layers = this.$store.state.map.layers;
     if (this.baseMaps.length > 0) {
       this.baseMaps[0].active = true;
-       this.activeBasemap=this.baseMaps[0];
+      this.activeBasemap = this.baseMaps[0];
       this.addLayers(this.baseMaps[0]);
     } else {
       mapUtil.addLayers(
@@ -313,11 +352,7 @@ export default {
         this.$store.state.configuration.DEFAULT_BASE_MAP.OPTIONS
       );
     }
-    setTimeout(this.initSortable.bind(this),1000)
-    
-   
-
-
+    setTimeout(this.initSortable.bind(this), 1000);
   },
 };
 </script>
diff --git a/src/components/project/ProjectMappingContextLayer.vue b/src/components/project/ProjectMappingContextLayer.vue
index 02837647f558390fbc411a13f495f80d20e86b50..9b732a334589c3b263cb0067bd770bfbc8093730 100644
--- a/src/components/project/ProjectMappingContextLayer.vue
+++ b/src/components/project/ProjectMappingContextLayer.vue
@@ -11,7 +11,7 @@
         <!--   {{ form.layer }} -->
         <!-- {% else %} -->
         <Dropdown
-          :options="availableLayers"
+          :options="availableLayerOptions"
           :selected="selectedLayer.name"
           :selection.sync="selectedLayer"
           :search="true"
@@ -70,23 +70,16 @@ export default {
   },
 
   computed: {
-    ...mapState("map", ["layers", "availableLayers"]),
+    ...mapState("map", ["availableLayers"]),
 
     selectedLayer: {
       get() {
-        const matchingLayer = this.retrieveLayer(this.layer.title);
-        if (matchingLayer != undefined) {
-          return {
-            name: matchingLayer != undefined ? matchingLayer.service : "",
-            value: this.layer ? this.layer.title : "",
-          };
-        }
-        return [];
+        return this.retrieveLayer(this.layer.title) || [];
       },
 
       set(newValue) {
         const matchingLayer = this.retrieveLayer(newValue.title);
-        if (matchingLayer != undefined) {
+        if (matchingLayer !== undefined) {
           this.updateLayer({
             ...this.layer,
             service: newValue.name,
@@ -109,11 +102,11 @@ export default {
       },
     },
 
-    availableLayers: function () {
-      return this.layers.map((el) => {
+    availableLayerOptions: function () {
+      return this.availableLayers.map((el) => {
         return {
           id: el.id,
-          name: el.service,
+          name: `${el.title} - ${el.service}`,
           value: el.title,
           title: el.title,
         };
@@ -122,14 +115,14 @@ export default {
 
     placeholder: function () {
       return this.selectedLayer && this.selectedLayer.name
-        ? this.selectedLayer.name
+        ? ""
         : "Choisissez une couche";
     },
   },
 
   methods: {
     retrieveLayer(title) {
-      return this.layers.find((el) => el.title === title);
+      return this.availableLayerOptions.find((el) => el.title === title);
     },
 
     removeLayer() {
@@ -150,7 +143,7 @@ export default {
 
   mounted() {
     const matchingLayer = this.retrieveLayer(this.layer.title);
-    if (matchingLayer != undefined) {
+    if (matchingLayer !== undefined) {
       this.updateLayer({
         ...this.layer,
         service: matchingLayer.service,
diff --git a/src/main.js b/src/main.js
index 22fdd2b3b48d5fa8a340a744abf90bded82bf99a..724a17140dc042cedd811c9027eb374e807a067d 100644
--- a/src/main.js
+++ b/src/main.js
@@ -20,7 +20,7 @@ axios.get("/config/config.json")
               store.dispatch("GET_ALL_PROJECTS"),
               store.dispatch("GET_STATIC_PAGES"),
               store.dispatch("GET_USER_LEVEL_PROJECTS"),
-              store.dispatch("map/GET_LAYERS"),
+              store.dispatch("map/GET_AVAILABLE_LAYERS"),
               store.dispatch("GET_USER_LEVEL_PERMISSIONS"),
             ]).then(axios.spread(function () {
               new Vue({
diff --git a/src/services/project-api.js b/src/services/project-api.js
index fd46c39241a72d1928e49af49f081730d497da9c..b918ad2270c8dbcd20cd0d46f8c903af3176a3a4 100644
--- a/src/services/project-api.js
+++ b/src/services/project-api.js
@@ -5,7 +5,7 @@ import store from '../store'
 axios.defaults.headers.common['X-CSRFToken'] = (name => {
   var re = new RegExp(name + "=([^;]+)");
   var value = re.exec(document.cookie);
-  return (value != null) ? unescape(value[1]) : null;
+  return (value !== null) ? unescape(value[1]) : null;
 })('csrftoken');
 
 
diff --git a/src/store/index.js b/src/store/index.js
index 713cf40a33323737061d331985840c6e09a39361..329d9b0b684344a2d4a6da266d1715b3deb8c71e 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -10,7 +10,7 @@ import map from "./modules/map"
 axios.defaults.headers.common['X-CSRFToken'] = (name => {
   var re = new RegExp(name + "=([^;]+)");
   var value = re.exec(document.cookie);
-  return (value != null) ? unescape(value[1]) : null;
+  return (value !== null) ? unescape(value[1]) : null;
 })('csrftoken');
 
 
@@ -22,7 +22,7 @@ function updateAxiosHeader() {
   axios.defaults.headers.common['X-CSRFToken'] = (name => {
     var re = new RegExp(name + "=([^;]+)");
     var value = re.exec(document.cookie);
-    return (value != null) ? unescape(value[1]) : null;
+    return (value !== null) ? unescape(value[1]) : null;
   })('csrftoken');
 }
 // ! À vérifier s'il y a un changement de token pendant l'éxécution de l'appli
@@ -92,7 +92,10 @@ export default new Vuex.Store({
     },
     DISPLAY_MESSAGE(state, comment) {
       state.messages = [{ comment }, ...state.messages];
-      document.getElementById("content").scrollIntoView({ block: "start", inline: "nearest" });
+      document.getElementById("messages").scrollIntoView({ block: "start", inline: "nearest" });
+      setTimeout(() => {
+        state.messages = [];
+      }, 3000);
     },
     CLEAR_MESSAGES(state) {
       state.messages = [];
diff --git a/src/store/modules/feature.js b/src/store/modules/feature.js
index 8b186bc236bdd069aaaf7f063adff57a06c3c4e4..02c889157156c82b25dfa1d9916228691c872d55 100644
--- a/src/store/modules/feature.js
+++ b/src/store/modules/feature.js
@@ -4,7 +4,7 @@ import router from '../../router'
 axios.defaults.headers.common['X-CSRFToken'] = (name => {
   var re = new RegExp(name + "=([^;]+)");
   var value = re.exec(document.cookie);
-  return (value != null) ? unescape(value[1]) : null;
+  return (value !== null) ? unescape(value[1]) : null;
 })('csrftoken');
 
 
diff --git a/src/store/modules/feature_type.js b/src/store/modules/feature_type.js
index 1ef68a93448748fdd2c13dc533fba5f02c6714df..a763e047ceb1110cf6576881b9f42d6403e425ed 100644
--- a/src/store/modules/feature_type.js
+++ b/src/store/modules/feature_type.js
@@ -3,7 +3,7 @@ import axios from "axios"
 axios.defaults.headers.common['X-CSRFToken'] = (name => {
   var re = new RegExp(name + "=([^;]+)");
   var value = re.exec(document.cookie);
-  return (value != null) ? unescape(value[1]) : null;
+  return (value !== null) ? unescape(value[1]) : null;
 })('csrftoken');
 
 
diff --git a/src/store/modules/map.js b/src/store/modules/map.js
index 76cfc0bcdd942f9380b417c3e73cc9014587ccce..d47afc9ef721f6a3201ff1db473b051c92552a1e 100644
--- a/src/store/modules/map.js
+++ b/src/store/modules/map.js
@@ -4,7 +4,7 @@ import { mapUtil } from "@/assets/js/map-util.js";
 axios.defaults.headers.common['X-CSRFToken'] = (name => {
   var re = new RegExp(name + "=([^;]+)");
   var value = re.exec(document.cookie);
-  return (value != null) ? unescape(value[1]) : null;
+  return (value !== null) ? unescape(value[1]) : null;
 })('csrftoken');
 
 
@@ -15,11 +15,11 @@ const map = {
     basemapsToDelete: [],
     features: [],
     geojsonFeatures: null,
-    layers: null,
+    availableLayers: null,
   },
   mutations: {
-    SET_LAYERS(state, layers) {
-      state.layers = layers;
+    SET_LAYERS(state, availableLayers) {
+      state.availableLayers = availableLayers;
     },
     SET_GEOJSON_FEATURES(state, geojsonFeatures) {
       state.geojsonFeatures = geojsonFeatures;
@@ -87,7 +87,7 @@ const map = {
   },
 
   actions: {
-    GET_LAYERS({ commit }) {
+    GET_AVAILABLE_LAYERS({ commit }) {
       return axios
         .get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}layers/`)
         .then((response) => (commit("SET_LAYERS", response.data)))
@@ -138,7 +138,7 @@ const map = {
             : 0;
         layersToLoad = state.baseMaps[basemapIndex].layers;
         layersToLoad.forEach((layerToLoad) => {
-          state.layers.forEach((layer) => {
+          state.availableLayers.forEach((layer) => {
             if (layer.id === layerToLoad.id) {
               layerToLoad = Object.assign(layerToLoad, layer);
             }
diff --git a/src/views/feature/Feature_detail.vue b/src/views/feature/Feature_detail.vue
index c1a5260d995a927fe087fbad2379afa4a0fb723d..1a1dd773c9dcee010166c237b86b973dc046dbf0 100644
--- a/src/views/feature/Feature_detail.vue
+++ b/src/views/feature/Feature_detail.vue
@@ -563,7 +563,7 @@ export default {
       // - if not, load the default map and service options
       let layersToLoad = null;
       var baseMaps = this.$store.state.map.basemaps;
-      var layers = this.$store.state.map.layers;
+      var layers = this.$store.state.map.availableLayers;
       if (baseMaps && baseMaps.length > 0) {
         const basemapIndex = 0;
         layersToLoad = baseMaps[basemapIndex].layers;
@@ -599,7 +599,7 @@ export default {
           if (feature) {
             const currentFeature = [feature];
             const featureGroup = mapUtil.addFeatures(currentFeature);
-            mapUtil.getMap().fitBounds(featureGroup.getBounds());
+            mapUtil.getMap().fitBounds(featureGroup.getBounds(), { padding: [25, 25] });
           }
         })
         .catch((error) => {
diff --git a/src/views/feature/Feature_edit.vue b/src/views/feature/Feature_edit.vue
index bf455ac417517635948694ad077698dda856b37a..cefa6f35cbb71d4d7ba9b5fb7bb21b0cb5785199 100644
--- a/src/views/feature/Feature_edit.vue
+++ b/src/views/feature/Feature_edit.vue
@@ -250,7 +250,7 @@ import flip from "@turf/flip";
 axios.defaults.headers.common["X-CSRFToken"] = ((name) => {
   var re = new RegExp(name + "=([^;]+)");
   var value = re.exec(document.cookie);
-  return value != null ? unescape(value[1]) : null;
+  return value !== null ? unescape(value[1]) : null;
 })("csrftoken");
 
 export default {
@@ -838,7 +838,7 @@ export default {
         } else if (geomType === "polygon") {
           L.polygon(geomJSON.coordinates).addTo(this.drawnItems);
         }
-        this.map.fitBounds(this.drawnItems.getBounds());
+        this.map.fitBounds(this.drawnItems.getBounds(), { padding: [25, 25] });
       } else {
         this.map.setView(
           this.$store.state.configuration.DEFAULT_MAP_VIEW.center,
diff --git a/src/views/feature/Feature_list.vue b/src/views/feature/Feature_list.vue
index fb5d7ff0fc43efae37ceb4f73e503164e3f54938..79b7f1342d4563e29850e5e7793f52d0eaa0c0b7 100644
--- a/src/views/feature/Feature_list.vue
+++ b/src/views/feature/Feature_list.vue
@@ -93,6 +93,7 @@
           :selected="form.type.selected"
           :selection.sync="form.type.selected"
           :search="true"
+          :clearable="true"
         />
       </div>
       <div class="field wide four column no-padding-mobile no-margin-mobile">
@@ -104,6 +105,7 @@
           :selected="form.status.selected.name"
           :selection.sync="form.status.selected"
           :search="true"
+          :clearable="true"
         />
       </div>
       <div class="field wide four column">
@@ -333,7 +335,9 @@ export default {
       this.featureGroup.clearLayers();
       this.featureGroup = mapUtil.addFeatures(features, {});
       if (features.length > 0) {
-        mapUtil.getMap().fitBounds(this.featureGroup.getBounds());
+        mapUtil
+          .getMap()
+          .fitBounds(this.featureGroup.getBounds(), { padding: [25, 25] });
       }
     },
 
@@ -402,7 +406,9 @@ export default {
         (this.lat === "" || this.lng === "" || this.zoom === "") &&
         this.geojsonFeatures.length > 0
       ) {
-        mapUtil.getMap().fitBounds(this.featureGroup.getBounds());
+        mapUtil
+          .getMap()
+          .fitBounds(this.featureGroup.getBounds(), { padding: [25, 25] });
       }
       this.form.type.choices = [
         //* converting Set to an Array with spread "..."
diff --git a/src/views/project/Project_detail.vue b/src/views/project/Project_detail.vue
index ddff358b08a2ed0bdacf60f88b1f951ce7f11252..b7fbff0231327a8f1606f9182f26e87add209dc2 100644
--- a/src/views/project/Project_detail.vue
+++ b/src/views/project/Project_detail.vue
@@ -589,7 +589,9 @@ export default {
           const features = response.data.features;
           const featureGroup = mapUtil.addFeatures(features);
           if (featureGroup && featureGroup.getLayers().length > 0) {
-            mapUtil.getMap().fitBounds(featureGroup.getBounds());
+            mapUtil
+              .getMap()
+              .fitBounds(featureGroup.getBounds(), { padding: [25, 25] });
             self.$store.commit("map/SET_GEOJSON_FEATURES", features);
           }
         })
diff --git a/src/views/project/Project_edit.vue b/src/views/project/Project_edit.vue
index 4d250f598a9afc0f5a2acfe376fa1954f074c213..7bbf384af7270a9e3657214bde60d19468d5887d 100644
--- a/src/views/project/Project_edit.vue
+++ b/src/views/project/Project_edit.vue
@@ -199,7 +199,7 @@ import { mapGetters } from "vuex";
 axios.defaults.headers.common["X-CSRFToken"] = ((name) => {
   var re = new RegExp(name + "=([^;]+)");
   var value = re.exec(document.cookie);
-  return value != null ? unescape(value[1]) : null;
+  return value !== null ? unescape(value[1]) : null;
 })("csrftoken");
 
 export default {
diff --git a/src/views/project/Project_members.vue b/src/views/project/Project_members.vue
index bb03c3d8e0f18ab5e9b3b6b4364ba77b8db70b35..a838d755e80c0131efa9de35a3b5b1c63955eea9 100644
--- a/src/views/project/Project_members.vue
+++ b/src/views/project/Project_members.vue
@@ -107,6 +107,12 @@ export default {
         .then((response) => {
           if (response.status === 200) {
             this.$store.dispatch("GET_USER_LEVEL_PROJECTS"); //* update user status in top right menu
+            this.$store.commit("DISPLAY_MESSAGE", "Permissions mises à jour");
+          } else {
+            this.$store.commit(
+              "DISPLAY_MESSAGE",
+              "Une erreur s'est produite pendant la mises à jour des permissions"
+            );
           }
         })
         .catch((error) => {