diff --git a/dump.rdb b/dump.rdb
new file mode 100644
index 0000000000000000000000000000000000000000..8783eda81682fd23bb8226256569cdf2cbb774c8
Binary files /dev/null and b/dump.rdb differ
diff --git a/package-lock.json b/package-lock.json
index f8d9c588927356a3fc1d970f356e0f95f2e09dbb..b9feb38fa0dfc01131688a519bd57ae63f2bb9a2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,11 +1,11 @@
 {
   "name": "geocontrib-frontend",
-  "version": "0.1.0",
+  "version": "2.0.0",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
-      "version": "0.1.0",
+      "version": "2.0.0",
       "dependencies": {
         "@turf/flip": "^6.5.0",
         "axios": "^0.21.1",
@@ -13,6 +13,7 @@
         "leaflet": "^1.5.1",
         "leaflet-draw": "^1.0.4",
         "register-service-worker": "^1.7.1",
+        "sortablejs": "^1.14.0",
         "vue": "^2.6.11",
         "vue-frag": "^1.1.5",
         "vue-router": "^3.2.0",
@@ -11965,6 +11966,11 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/sortablejs": {
+      "version": "1.14.0",
+      "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.14.0.tgz",
+      "integrity": "sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w=="
+    },
     "node_modules/source-list-map": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
@@ -24967,6 +24973,11 @@
         }
       }
     },
+    "sortablejs": {
+      "version": "1.14.0",
+      "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.14.0.tgz",
+      "integrity": "sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w=="
+    },
     "source-list-map": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
diff --git a/package.json b/package.json
index 82643726b78a2c83bc544034804ddfc071f621a3..2478d2e70f01edc50b444a82211943ea7f3e4e3b 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,7 @@
     "leaflet": "^1.5.1",
     "leaflet-draw": "^1.0.4",
     "register-service-worker": "^1.7.1",
+    "sortablejs": "^1.14.0",
     "vue": "^2.6.11",
     "vue-frag": "^1.1.5",
     "vue-router": "^3.2.0",
diff --git a/public/index.html b/public/index.html
index bf81abbcae21b265ed11b24c7af08383604145a2..81a966830c494ff1621342f894af73bc9a031577 100644
--- a/public/index.html
+++ b/public/index.html
@@ -13,7 +13,11 @@
     <noscript>
       <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
     </noscript>
-    <div id="app"></div>
+    <div id="app">
+      <div class="ui active dimmer">
+        <div class="ui indeterminate text loader">En cours de chargement ...</div>
+      </div>
+    </div>
     <!-- built files will be auto injected -->
   </body>
 </html>
diff --git a/src/App.vue b/src/App.vue
index 253411d263b7ed5c2e2cebced7d6825c896c41c4..af09408b2e3ebd0d516dbe4a0b23bd1836698e8d 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -8,7 +8,7 @@
               class="ui mini right spaced image"
               src="@/assets/img/logo-neogeo-circle.png"
             />
-              <!-- :src="LOGO_PATH" -->
+            <!-- :src="LOGO_PATH" -->
             {{ getApplicationName() }}
           </router-link>
 
@@ -44,6 +44,7 @@
               </router-link>
 
               <router-link
+                v-if="user.is_administrator"
                 :to="{
                   name: 'project_mapping',
                   params: { slug: project.slug },
@@ -53,6 +54,7 @@
                 <i class="map icon"></i>Fonds cartographiques
               </router-link>
               <router-link
+                v-if="user.is_administrator"
                 :to="{
                   name: 'project_members',
                   params: { slug: project.slug },
@@ -61,14 +63,12 @@
               >
                 <i class="users icon"></i>Membres
               </router-link>
-              <!-- {% endif %} -->
             </div>
           </div>
 
           <div class="right menu">
             <router-link v-if="user" to="/my_account/" class="item">
               {{ userFullname || user.username || "Utilisateur inconnu" }}
-              <!-- // ? full_name n'existe pas côté django... -->
             </router-link>
             <div
               v-if="user && user.is_administrator"
@@ -81,8 +81,6 @@
               <span v-if="user.is_administrator"> Gestionnaire métier </span>
             </div>
             <!-- // todo : find out SSO_SETTED in django -->
-            <!-- // ? condition bizarre (if !sso_setted pui elif !sso_setted)  ? -->
-            <!-- <a  class="item" href="{% url 'geocontrib:logout' %}"><i class="ui logout icon"></i></a> -->
             <a v-if="user && !SSO_SETTED" @click="logout" class="item"
               ><i class="ui logout icon"></i>
             </a>
@@ -95,8 +93,6 @@
     </header>
     <main>
       <div class="ui stackable grid centered container">
-        <!-- // todo : add messages -->
-        <!--  {% if messages %} -->
         <div v-if="messages" class="row">
           <div class="fourteen wide column">
             <div
@@ -117,7 +113,6 @@
             </div>
           </div>
         </div>
-        <!-- {% endif %} -->
         <router-view />
         <!-- //* Les views sont injectées ici -->
       </div>
@@ -134,7 +129,6 @@
 </template>
 
 <script>
-
 import frag from "vue-frag";
 import { mapState } from "vuex";
 import { mapGetters } from "vuex";
@@ -154,7 +148,13 @@ export default {
   },
 
   computed: {
-    ...mapState(["projects", "user", "SSO_SETTED", "USER_LEVEL_PROJECTS","configuration"]),
+    ...mapState([
+      "projects",
+      "user",
+      "SSO_SETTED",
+      "USER_LEVEL_PROJECTS",
+      "configuration",
+    ]),
     ...mapGetters(["project"]),
     //LOGO_PATH: () => require(`${configuration.VUE_APP_LOGO_PATH}`),
     //APPLICATION_NAME: () => this.configuration.VUE_APP_APPLICATION_NAME,
diff --git a/src/assets/js/map-util.js b/src/assets/js/map-util.js
index 2bb0f78e4a4cc104f50751ca06cd87412feaf234..89acc5e36ddc956b36bb996065b2988299592335 100644
--- a/src/assets/js/map-util.js
+++ b/src/assets/js/map-util.js
@@ -32,18 +32,19 @@ L.TileLayer.BetterWMS = L.TileLayer.WMS.extend({
   getFeatureInfo: function (evt) {
     if (this.wmsParams.basemapId != undefined) {
       const queryableLayerSelected = document.getElementById(`queryable-layers-selector-${this.wmsParams.basemapId}`).getElementsByClassName('selected')[0].innerHTML;
-      if (queryableLayerSelected === this.wmsParams.title) {
+      if (queryableLayerSelected.trim() === this.wmsParams.title.trim()) {
         // Make an AJAX request to the server and hope for the best
         var params = this.getFeatureInfoUrl(evt.latlng);
         var showResults = L.Util.bind(this.showGetFeatureInfo, this);
 
-        axios.post(
+        axios.get(
           window.proxy_url,
           {
-            data: params,
+            params: params,
             //dataType: "json",
           }
-            .then(data => {
+            ).then(response => {
+              let data=response.data;
               var err = typeof data === 'object' ? null : data;
               if (data.features || err) {
                 showResults(err, evt.latlng, data);
@@ -55,7 +56,7 @@ L.TileLayer.BetterWMS = L.TileLayer.WMS.extend({
               //xhr.responseText;
               //console.log(status)
             }
-            ))
+            )
 
       }
     }
@@ -176,7 +177,31 @@ const mapUtil = {
 
     return map;
   },
+  addGeocoders: function(configuration){
+    let geocoder;
+    const geocoderLabel = configuration.SELECTED_GEOCODER.PROVIDER;
+    if (geocoderLabel) {
+      const LIMIT_RESULTS = 5;
+      if (
+        geocoderLabel === configuration.GEOCODER_PROVIDERS.ADDOK
+      ) {
+        geocoder = L.Control.Geocoder.addok({ limit: LIMIT_RESULTS });
+      } else if (
+        geocoderLabel === configuration.GEOCODER_PROVIDERS.PHOTON
+      ) {
+        geocoder = L.Control.Geocoder.photon();
+      } else if (
+        geocoderLabel === configuration.GEOCODER_PROVIDERS.NOMINATIM
+      ) {
+        geocoder = L.Control.Geocoder.nominatim();
+      }
 
+      L.Control.geocoder({
+        placeholder: "Chercher une adresse...",
+        geocoder: geocoder,
+      }).addTo(map);
+    }
+  },
   addLayers: function (layers, serviceMap, optionsMap) {
     if (layers) {
       layers.forEach((layer) => {
diff --git a/src/components/Dropdown.vue b/src/components/Dropdown.vue
index 0ca8e093114e5bfc7bfac0e1dc348f2b3b2d9528..d55ed84c1d11548e2e5836839fef1f08c2b14f38 100644
--- a/src/components/Dropdown.vue
+++ b/src/components/Dropdown.vue
@@ -33,9 +33,7 @@
           processedOptions ? 'item' : 'message',
           { 'active selected': option === selected },
         ]"
-      >
-        {{ option }}
-      </div>
+      >{{ option }}</div>
     </div>
   </div>
 </template>
diff --git a/src/components/map-layers/SidebarLayers.vue b/src/components/map-layers/SidebarLayers.vue
index 9df2338dce40fc89bd337a1011da9e8bd6af6d2a..d1120637b947ea8df5d629c4f1133823b27fcfe2 100644
--- a/src/components/map-layers/SidebarLayers.vue
+++ b/src/components/map-layers/SidebarLayers.vue
@@ -47,7 +47,7 @@
 
     <div
       v-for="basemap in baseMaps"
-      :id="`list-${basemap.id}`"
+      
       :key="`list-${basemap.id}`"
       class="basemaps-items ui accordion styled"
     >
@@ -58,15 +58,26 @@
       >
         {{ basemap.title }}
       </div>
+      <div :id="`queryable-layers-selector-${basemap.id}`" v-if="isQueryable(basemap)">
+        <b>Couche requêtable</b>
+        <Dropdown 
+          @update:selection="onQueryLayerChange($event)"
+          :options="getQueryableLayers(basemap)"
+          :selected="selectedQueryLayer"
+          :search="true"
+        />
+
+      </div>
       <div
         :class="{ active: isActive(basemap) }"
         class="content"
-        data-basemap-index="0"
+        :id="`list-${basemap.id}`"
+        :data-basemap-index="basemap.id"
       >
         <div
           v-for="(layer, index) in basemap.layers"
           :key="basemap.id + '-' + layer.id + '-' + index"
-          class="layer-item transition visible"
+          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 }}
@@ -94,11 +105,18 @@
 
 <script>
 import { mapUtil } from "@/assets/js/map-util.js";
+import Dropdown from "@/components/Dropdown.vue";
+import Sortable from 'sortablejs';
 
 export default {
   name: "SidebarLayers",
+  components: {
+    Dropdown,
+  },
   data() {
     return {
+      selectedQueryLayer:null,
+      activeBasemap:null,
       baseMaps: [],
       layers: [],
       expanded: false,
@@ -111,8 +129,20 @@ export default {
     activateGroup(basemap) {
       this.baseMaps.forEach((basemap) => (basemap.active = false));
       basemap.active = true;
+      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));
+
+
     },
     updateOpacity(event, layer) {
       console.log(event.target.value, layer);
@@ -122,7 +152,118 @@ export default {
     getOpacity(opacity) {
       return Math.round(parseFloat(opacity) * 100);
     },
+    onQueryLayerChange(layer){
+      console.log(layer);
+      this.selectedQueryLayer=layer.name;
+    },
+    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);
+
+      // 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]);
+      }
+
+      // Remove existing layers undefined
+      movedLayers = movedLayers.filter(function(x) {
+        return x !== undefined;
+      });
+      const eventOrder = new CustomEvent('change-layers-order', {
+        detail: {
+          layers: movedLayers
+        }
+      })
+      document.dispatchEvent(eventOrder);
+      // Save the basemaps options into the localstorage
+      console.log(this.baseMaps)
+      this.setLocalstorageMapOptions(this.baseMaps)
+    },
+    setLocalstorageMapOptions(basemaps) {
+      let mapOptions = localStorage.getItem('geocontrib-map-options') || {};
+      mapOptions = mapOptions.length ? JSON.parse(mapOptions) : {};
+      let project=this.$route.params.slug;
+      mapOptions[project] = {
+        ...mapOptions[project],
+        'basemaps': basemaps
+      };
+      localStorage.setItem('geocontrib-map-options', JSON.stringify(mapOptions));
+    },
+
+    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)
+          });
+      });
+    },
+
+    // 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;
+              }
+            }
+          }
+        }
+      }
+
+      // 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]);
+
+      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 {
+          name:x.title,
+          value:x
+        }
+      });
+    },
     addLayers(baseMap) {
+     
       baseMap.layers.forEach((layer) => {
         var layerOptions = this.layers.find((l) => l.id == layer.id);
         console.log(layerOptions);
@@ -137,9 +278,33 @@ export default {
   },
   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 
+      // 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);
+
+      if (areChanges) {
+        mapOptions[project] = {
+          'map-options': this.baseMaps,
+          'current-basemap-index': 0,
+        };
+        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.addLayers(this.baseMaps[0]);
     } else {
       mapUtil.addLayers(
@@ -148,6 +313,11 @@ export default {
         this.$store.state.configuration.DEFAULT_BASE_MAP.OPTIONS
       );
     }
+    setTimeout(this.initSortable.bind(this),1000)
+    
+   
+
+
   },
 };
 </script>
diff --git a/src/components/project/ProjectMappingContextLayer.vue b/src/components/project/ProjectMappingContextLayer.vue
index 12bbd9f74c32e8c32a4cdc3a3e8b02f42850e638..9a766ca27c1a80d0ffb2ec5f67187d951db2179b 100644
--- a/src/components/project/ProjectMappingContextLayer.vue
+++ b/src/components/project/ProjectMappingContextLayer.vue
@@ -68,20 +68,25 @@ export default {
     selectedLayer: {
       get() {
         const matchingLayer = this.retrieveLayer(this.layer.title);
-        return {
-          name: matchingLayer ? matchingLayer.service : "",
-          value: this.layer ? this.layer.title : "",
-        };
+        if (matchingLayer != undefined){
+          return {
+            name: matchingLayer != undefined ? matchingLayer.service : "",
+            value: this.layer ? this.layer.title : "",
+          };
+        }
+        return []
       },
 
       set(newValue) {
-        const matchingLayer = this.retrieveLayer(this.layer.title);
-        this.updateLayer({
-          ...this.layer,
-          service: newValue.name,
-          title: newValue.value,
-          id: matchingLayer.id,
-        });
+        const matchingLayer = this.retrieveLayer(newValue.title);
+        if (matchingLayer != undefined){
+          this.updateLayer({
+            ...this.layer,
+            service: newValue.name,
+            title: newValue.value,
+            id:  matchingLayer.id,
+          });
+        }
       },
     },
 
@@ -96,7 +101,7 @@ export default {
 
     availableLayers: function () {
       return this.layers.map((el) => {
-        return { name: el.service, value: el.title };
+        return { id: el.id, name: el.service, value: el.title, title: el.title };
       });
     },
 
@@ -109,7 +114,7 @@ export default {
 
   methods: {
     retrieveLayer(title) {
-     return this.layers.find((el) => el.title === title);
+      return this.layers.find((el) => el.title === title);
     },
 
     removeLayer() {
@@ -130,12 +135,14 @@ export default {
 
   mounted() {
     const matchingLayer = this.retrieveLayer(this.layer.title);
-    this.updateLayer({
-      ...this.layer,
-      service: matchingLayer.service,
-      title: matchingLayer.title,
-      id: matchingLayer.id,
-    });
+    if (matchingLayer != undefined){
+      this.updateLayer({
+        ...this.layer,
+        service: matchingLayer.service,
+        title: matchingLayer.title,
+        id: matchingLayer.id,
+      });
+    }
   },
 };
 </script>
\ No newline at end of file
diff --git a/src/main.js b/src/main.js
index 0dc0f54a41b1aa150371eb2267f8eb8d4128990d..22fdd2b3b48d5fa8a340a744abf90bded82bf99a 100644
--- a/src/main.js
+++ b/src/main.js
@@ -14,7 +14,8 @@ Vue.config.productionTip = false
 axios.get("/config/config.json")
   .then((response) => {
     if (response && response.status === 200) {
-            store.commit("SET_CONFIG", response.data)
+            store.commit("SET_CONFIG", response.data);
+            window.proxy_url=response.data.VUE_APP_DJANGO_API_BASE+"proxy/"
             axios.all([store.dispatch("USER_INFO"),
               store.dispatch("GET_ALL_PROJECTS"),
               store.dispatch("GET_STATIC_PAGES"),
diff --git a/src/services/feature-api.js b/src/services/feature-api.js
index 988a0a3a3fca8c0923295ac0e0de67700aed09ef..49e40e12cb27cfe4043577a7cc66ca307cbf64a7 100644
--- a/src/services/feature-api.js
+++ b/src/services/feature-api.js
@@ -4,6 +4,20 @@ import store from '../store'
 const baseUrl = store.state.configuration.VUE_APP_DJANGO_API_BASE;
 
 const featureAPI = {
+  async getFeatureEvents(featureId) {
+    const response = await axios.get(
+      `${baseUrl}features/${featureId}/events/`
+    );
+    if (
+      response.status === 200 &&
+      response.data
+    ) {
+      return response.data;
+    } else {
+      return null;
+    }
+  },
+
   async getFeatureAttachments(featureId) {
     const response = await axios.get(
       `${baseUrl}features/${featureId}/attachments/`
diff --git a/src/store/index.js b/src/store/index.js
index cb00de2006643cd9aeaa14a981a9b12726994edb..5035d682a0b278a2279c895d9deb3318b400fd56 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -3,7 +3,6 @@ const axios = require("axios");
 import Vue from 'vue';
 import Vuex from 'vuex';
 import router from '../router'
-//import modules from './modules';
 import feature_type from "./modules/feature_type"
 import feature from "./modules/feature"
 import map from "./modules/map"
@@ -29,6 +28,8 @@ function updateAxiosHeader() {
 // ! À vérifier s'il y a un changement de token pendant l'éxécution de l'appli
 updateAxiosHeader();
 
+const noPermissions = { "can_view_project": true, "can_create_project": false, "can_update_project": false, "can_view_feature": true, "can_view_archived_feature": true, "can_create_feature": false, "can_update_feature": false, "can_delete_feature": false, "can_publish_feature": false, "can_create_feature_type": false, "can_view_feature_type": true, "is_project_administrator": false }
+
 export default new Vuex.Store({
   modules: {
     feature_type,
@@ -39,7 +40,7 @@ export default new Vuex.Store({
     error: null,
     logged: false,
     user: false,
-    configuration:null,
+    configuration: null,
     project_slug: null,
     projects: [],
     last_comments: [],
@@ -51,7 +52,7 @@ export default new Vuex.Store({
 
   mutations: {
     error(state, data) {
-      return state.error = data
+      state.error = data;
     },
     SET_PROJECTS(state, projects) {
       state.projects = projects;
@@ -72,54 +73,55 @@ export default new Vuex.Store({
       state.users = payload;
     },
     SET_COOKIE(state, cookie) {
-      state.cookie = cookie
+      state.cookie = cookie;
     },
     SET_STATIC_PAGES(state, staticPages) {
-      state.staticPages = staticPages
+      state.staticPages = staticPages;
     },
     SET_SSO(state, SSO_SETTED) {
-      state.SSO_SETTED = SSO_SETTED
+      state.SSO_SETTED = SSO_SETTED;
     },
     SET_USER_LEVEL_PROJECTS(state, USER_LEVEL_PROJECTS) {
-      state.USER_LEVEL_PROJECTS = USER_LEVEL_PROJECTS
+      state.USER_LEVEL_PROJECTS = USER_LEVEL_PROJECTS;
     },
     SET_LOGGED(state, value) {
-      state.logged = value
+      state.logged = value;
     },
     SET_PROJECT_COMMENTS(state, last_comments) {
-      state.last_comments = last_comments
+      state.last_comments = last_comments;
     },
     SET_USER_PERMISSIONS(state, userPermissions) {
-      state.user_permissions = userPermissions
+      state.user_permissions = userPermissions;
     },
   },
 
   getters: {
     project: state => state.projects.find((project) => project.slug === state.project_slug),
+    permissions: state => state.user_permissions ? state.user_permissions[state.project_slug] : noPermissions,
     project_types: state => state.projects.filter(projet => projet.is_project_type),
-    project_user: state => state.projects.filter(projet => projet.creator === state.user.id), // todo: add id to user in api
+    project_user: state => state.projects.filter(projet => projet.creator === state.user.id),
   },
 
   actions: {
-    async GET_ALL_PROJECTS({ commit }) {
+    GET_ALL_PROJECTS({ commit }) {
       function parseDate(date) {
-        let dateArr = date.split("/").reverse()
-        return new Date(dateArr[0], dateArr[1] - 1, dateArr[2])
+        let dateArr = date.split("/").reverse();
+        return new Date(dateArr[0], dateArr[1] - 1, dateArr[2]);
       }
-      await axios
+      return axios
         .get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}projects/`)
         .then((response) => {
           if (response.status === 200 && response.data) {
             const orderedProjects = response.data.sort((a, b) => parseDate(b.created_on) - parseDate(a.created_on));
-            commit("SET_PROJECTS", orderedProjects)
+            commit("SET_PROJECTS", orderedProjects);
           }
         })
         .catch((error) => {
           throw error;
         });
     },
-    async GET_STATIC_PAGES({ commit }) {
-      await axios
+    GET_STATIC_PAGES({ commit }) {
+      return axios
         .get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}flat-pages/`)
         .then((response) => (commit("SET_STATIC_PAGES", response.data)))
         .catch((error) => {
@@ -135,50 +137,58 @@ export default new Vuex.Store({
             password: payload.password,
           })
           .then((response) => {
-            commit('error', null)
+            commit('error', null);
             if (response && response.status === 200) {
               // * use stored previous route to go back after login if page not open on login at first
-              let routerHistory = ''
-              if (router.options.routerHistory[0] != undefined){
-                routerHistory = router.options.routerHistory[0].name !== "login" ? router.options.routerHistory : "/"
+              let routerHistory = '';
+              if (router.options.routerHistory[0] !== undefined) {
+                routerHistory = router.options.routerHistory[0].name !== "login" ? router.options.routerHistory : "/";
               } else {
-                routerHistory = "/"
+                routerHistory = "/";
               }
               commit("SET_USER", response.data.user);
-              router.push(routerHistory[routerHistory.length - 1] || "/")
+              router.push(routerHistory[routerHistory.length - 1] || "/");
               dispatch("GET_USER_LEVEL_PROJECTS");
+              dispatch("GET_USER_LEVEL_PERMISSIONS")
             }
           })
           .catch((error) => {
-            if (error.response.status === 403)
-            commit('error', error.response.data.detail)
+            if (error.response.status === 403) {
+              commit('error', error.response.data.detail);
+            }
             commit("SET_USER", false);
           });
       }
     },
 
-    USER_INFO({ commit }) {
-      axios
-        .get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}user_info/`)
-        .then((response) => {
-          if (response && response.status === 200) {
-            const user = response.data.user;
-            commit("SET_USER", user);
-            window.localStorage.setItem("user", JSON.stringify(user)); //? toujours nécessaire ?
-          }
-        }) 
-        .catch(() => {
-          router.push({ name: "login" });
-        });
+    USER_INFO({ state, commit }) {
+      if (!state.user) {
+        axios
+          .get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}user_info/`)
+          .then((response) => {
+            if (response && response.status === 200) {
+              const user = response.data.user;
+              commit("SET_USER", user);
+              //window.localStorage.setItem("user", JSON.stringify(user)); // ? nécessaire ?
+            }
+          })
+          .catch(() => {
+            router.push({ name: "login" });
+          });
+      }
     },
 
-    LOGOUT({ commit }) { // ? logout se fait bien dans django ?
+    LOGOUT({ commit, dispatch }) {
+      // const pageNoRedirect = ["liste-signalements", "details-type-signalement", "details-signalement", "project_detail", "mentions", "aide", "index"]
       axios
         .get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}logout/`)
         .then((response) => {
           if (response && response.status === 200) {
-            commit("SET_USER", false); // ? better false or null
+            commit("SET_USER", false);
             commit("SET_USER_LEVEL_PROJECTS", null);
+            dispatch("GET_USER_LEVEL_PERMISSIONS");
+            // if (!pageNoRedirect.includes(router.history.current.name)) router.push("/");
+            router.push("/");
           }
         })
         .catch((error) => {
@@ -191,19 +201,20 @@ export default new Vuex.Store({
         .get("./config/config.json")
         .then((response) => {
           if (response && response.status === 200) {
-            commit("SET_CONFIG", response.data)
+            commit("SET_CONFIG", response.data);
           }
         })
         .catch((error) => {
           throw error;
         });
     },
+
     GET_USER_LEVEL_PROJECTS({ commit }) {
-      axios
+      return axios
         .get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}user-level-projects/`)
         .then((response) => {
           if (response && response.status === 200) {
-            commit("SET_USER_LEVEL_PROJECTS", response.data)
+            commit("SET_USER_LEVEL_PROJECTS", response.data);
           }
         })
         .catch((error) => {
@@ -212,11 +223,11 @@ export default new Vuex.Store({
     },
 
     GET_USER_LEVEL_PERMISSIONS({ commit }) {
-      axios
+      return axios
         .get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}user-permissions/`)
         .then((response) => {
           if (response && response.status === 200) {
-            commit("SET_USER_PERMISSIONS", response.data)
+            commit("SET_USER_PERMISSIONS", response.data);
           }
         })
         .catch((error) => {
@@ -224,70 +235,26 @@ export default new Vuex.Store({
         });
     },
 
-    GET_PROJECT_INFO({ commit, dispatch }, slug) {
+    GET_PROJECT_INFO({ state, commit, dispatch }, slug) {
       commit("SET_PROJECT_SLUG", slug);
       dispatch("GET_PROJECT_LAST_MESSAGES", slug);
       dispatch("feature_type/GET_PROJECT_FEATURE_TYPES", slug);
       dispatch("feature/GET_PROJECT_FEATURES", slug);
-      dispatch("map/GET_BASEMAPS", slug);
+      if (state.user) dispatch("map/GET_BASEMAPS", slug);
     },
 
     GET_PROJECT_LAST_MESSAGES({ commit }, project_slug) {
-      axios
+      return axios
         .get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${project_slug}/comments/`)
         .then((response) => {
           if (response && response.status === 200) {
-            commit("SET_PROJECT_COMMENTS", response.data.last_comments)
+            commit("SET_PROJECT_COMMENTS", response.data.last_comments);
           }
         })
         .catch((error) => {
           throw error;
         });
     },
-
-    /* GET_PROJECT_FEATURES({ commit }, project_slug) {
-      axios
-        .get(`${DJANGO_API_BASE}projects/${project_slug}/feature`)
-        .then((response) => commit("feature/SET_FEATURES", response.data.features))
-        .catch((error) => {
-          throw error;
-        });
-    }, */
-    /* GET_PROJECT({ commit }, project_slug) {
-      axios
-        .get(`${DJANGO_API_BASE}projects/${project_slug}/project`)
-        .then((response) => commit("SET_PROJECT", response.data))
-        .catch((error) => {
-          throw error;
-        });
-    },
-    GET_PROJECT_USER({ commit }, project_slug) {
-      axios
-        .get(`${DJANGO_API_BASE}projects/${project_slug}/utilisateurs`)
-        .then((response) => (commit("SET_PROJECT_MEMBERS", response.data.members)))
-        .catch((error) => {
-          throw error;
-        });
-    }, */
-    /* GET_COOKIE({ commit }, name) {
-      let cookieValue = null;
-
-      if (document.cookie && document.cookie !== "") {
-        const cookies = document.cookie.split(";");
-        for (let i = 0; i < cookies.length; i++) {
-          const cookie = cookies[i].trim();
-
-          // Does this cookie string begin with the name we want?
-          if (cookie.substring(0, name.length + 1) === name + "=") {
-            cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
-
-            break;
-          }
-        }
-      }
-      commit("SET_COOKIE", cookieValue);
-    }, */
-
   }
 
 });
diff --git a/src/store/modules/feature.js b/src/store/modules/feature.js
index 03c124a1b8bb0345fcf56332e85c5e2bfd6b2ca2..60df940e2d32e0468710621e3c9e1bf6c21693ef 100644
--- a/src/store/modules/feature.js
+++ b/src/store/modules/feature.js
@@ -67,9 +67,9 @@ const feature = {
   getters: {
   },
   actions: {
-    GET_PROJECT_FEATURES({ commit, /* dispatch */ }, project_slug) {
+    GET_PROJECT_FEATURES({ commit, rootState }, project_slug) {
       axios
-        .get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${project_slug}/feature/`)
+        .get(`${rootState.configuration.VUE_APP_DJANGO_API_BASE}projects/${project_slug}/feature/`)
         .then((response) => {
           if (response.status === 200 && response.data) {
             const features = response.data.features;
@@ -103,14 +103,15 @@ const feature = {
 
       if (routeName === "editer-signalement") {
         axios
-          .put(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}features/${state.form.feature_id}/`, geojson)
+          .put(`${rootState.configuration.VUE_APP_DJANGO_API_BASE}features/${state.form.feature_id}/`, geojson)
           .then((response) => {
             if (response.status === 200 && response.data) {
               router.push({
-                name: "project_detail",
+                name: "details-signalement",
                 params: {
-                  slug: rootState.project_slug,
-                  message: "Le signalement a été mis à jour",
+                  slug_type_signal: rootState.feature_type.current_feature_type_slug,
+                  slug_signal: state.form.feature_id,
+                  //message: "Le signalement a été mis à jour",
                 },
               });
             }
@@ -120,15 +121,16 @@ const feature = {
           });
       } else {
         axios
-          .post(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}features/`, geojson)
+          .post(`${rootState.configuration.VUE_APP_DJANGO_API_BASE}features/`, geojson)
           .then((response) => {
             if (response.status === 201 && response.data) {
               dispatch("SEND_ATTACHMENTS", response.data.id)
               router.push({
-                name: "project_detail",
+                name: "details-signalement",
                 params: {
-                  slug: rootState.project_slug,
-                  message: "Le signalement a été crée",
+                  slug_type_signal: rootState.feature_type.current_feature_type_slug,
+                  slug_signal: response.data.id,
+                  //message: "Le signalement a été crée",
                 },
               });
             }
@@ -139,7 +141,7 @@ const feature = {
       }
     },
 
-    SEND_ATTACHMENTS({ state }, featureId) {
+    SEND_ATTACHMENTS({ state, rootState }, featureId) {
       for (let attacht of state.attachmentFormset) {
         let formdata = new FormData();
         formdata.append("file", attacht.fileToImport, attacht.fileToImport.name);
@@ -149,7 +151,7 @@ const feature = {
         }
         formdata.append("data", JSON.stringify(data));
         axios
-          .post(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}features/${featureId}/attachments/`, formdata)
+          .post(`${rootState.configuration.VUE_APP_DJANGO_API_BASE}features/${featureId}/attachments/`, formdata)
           .then((response) => {
             if (response.status === 200 && response.data) {
               console.log(response, response.data)
@@ -167,14 +169,23 @@ const feature = {
             .getlinked_features(featureId)
             .then((data) => commit("SET_FEATURE_LINKS", data));
         } */
-    //DELETE_FEATURE({ state }, feature_slug) {
-    //console.log("Deleting feature:", feature_slug, state)
+    DELETE_FEATURE({ state, rootState }, feature_id) {
+      console.log("Deleting feature:", feature_id, state)
+      const url = `${rootState.configuration.VUE_APP_DJANGO_API_BASE}features/${feature_id}`;
+      axios
+        .delete(url, {
+        })
+        .then()
+        .catch(() => {
+          return false;
+        });
+    },
 
     // POST_COMMENT({ state }, data) {
     //console.log("post comment", data, state)
 
     /* axios
-      .post(`${DJANGO_API_BASE}feature_type/`, data)
+      .post(`${rootState.configuration.VUE_APP_DJANGO_API_BASE}feature_type/`, data)
       .then((response) => {
         const routerHistory = router.options.routerHistory 
         commit("SET_USER", response.data.user);
@@ -192,4 +203,4 @@ const feature = {
 
 }
 
-export default feature
\ No newline at end of file
+export default feature
diff --git a/src/store/modules/feature_type.js b/src/store/modules/feature_type.js
index f4148c1783d7d4c6ecc97ea7186b0bb418d12296..68ef9d09cb92ca9acb634d1faf87b83cb28593c4 100644
--- a/src/store/modules/feature_type.js
+++ b/src/store/modules/feature_type.js
@@ -71,7 +71,7 @@ const feature_type = {
   },
   actions: {
     GET_PROJECT_FEATURE_TYPES({ commit }, project_slug) {
-      axios
+      return axios
         .get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${project_slug}/feature-types/`)
         .then((response) => commit("SET_FEATURE_TYPES", response.data.feature_types))
         .catch((error) => {
diff --git a/src/store/modules/map.js b/src/store/modules/map.js
index f29ef9f4d128729e027c6364005edcad240fce6c..719eb697116a3ff7bc211f4bd0a8093de6ab34fc 100644
--- a/src/store/modules/map.js
+++ b/src/store/modules/map.js
@@ -88,7 +88,7 @@ const map = {
 
   actions: {
     GET_LAYERS({ commit }) {
-      axios
+      return axios
         .get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}layers/`)
         .then((response) => (commit("SET_LAYERS", response.data)))
         .catch((error) => {
@@ -97,9 +97,11 @@ const map = {
     },
 
     GET_BASEMAPS({ commit }, project_slug) {
-      axios
+      return axios
         .get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}base-maps/?project__slug=${project_slug}`)
-        .then((response) => (commit("SET_BASEMAPS", response.data)))
+        .then((response) => {
+          commit("SET_BASEMAPS", response.data)
+        })
         .catch((error) => {
           throw error;
         });
@@ -153,43 +155,59 @@ const map = {
 
 
     SAVE_BASEMAPS({ state, rootState, dispatch }, newBasemapIds) {
-      for (let basemap of state.basemaps) {
-        basemap["project"] = rootState.project_slug
-        // TODO: différencier PUT & POST
-        console.log(newBasemapIds.includes(basemap.id), newBasemapIds, basemap.id);
-        if (newBasemapIds.includes(basemap.id)) {
-          axios
-            .post(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}base-maps/`, basemap)
-            .then((response) => (console.log(response.data)))
-            .catch((error) => {
-              throw error;
-            });
-        } else {
-          axios
-            .put(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}base-maps/${basemap.id}/`, basemap)
-            .then((response) => (console.log(response.data)))
-            .catch((error) => {
-              throw error;
-            });
+      return new Promise((resolve, reject) => {
+        for (let basemap of state.basemaps) {
+          basemap["project"] = rootState.project_slug
+          // TODO: différencier PUT & POST
+          if (newBasemapIds.includes(basemap.id)) {
+            axios
+              .post(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}base-maps/`, basemap)
+              .then((response) => {
+                resolve(response);
+              })
+              .catch((error) => {
+                reject(error);
+                throw error;
+              });
+          } else {
+            axios
+              .put(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}base-maps/${basemap.id}/`, basemap)
+              .then((response) => {
+                resolve(response);
+              })
+              .catch((error) => {
+                reject(error);
+                throw error;
+              });
+          }
         }
-      }
-      //* delete in the backend the basemaps that was rewoved from the front
-      for (let basemapId of state.basemapsToDelete) {
-        dispatch("DELETE_BASEMAP", basemapId);
-      }
+        //* delete in the backend the basemaps that was rewoved from the front
+        for (let basemapId of state.basemapsToDelete) {
+          dispatch("DELETE_BASEMAP", basemapId)
+          .then((response) =>{
+            resolve(response);
+          });
+        }
+        state.basemapsToDelete = []
+      });
     },
 
     DELETE_BASEMAP({ commit }, basemapId) {
-      axios
-        .delete(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}base-maps/`, basemapId)
+      return new Promise((resolve, reject) => {
+        let url = `${this.state.configuration.VUE_APP_DJANGO_API_BASE}base-maps/` + basemapId
+        axios
+        .delete(url)
         .then((response) => {
           if (response && response.status === 200) {
             commit("REMOVE_BASEMAP_ID_TO_DELETE", basemapId)
           }
+          resolve(response);
         })
         .catch((error) => {
+          reject(error);
           throw error;
         });
+      });
     }
   },
 }
diff --git a/src/views/My_account.vue b/src/views/My_account.vue
index c05a6d27d60e16d6ba70681c7620b924ecc8ba88..71f80d9e272087dbeb08401e63c94ac73219d8eb 100644
--- a/src/views/My_account.vue
+++ b/src/views/My_account.vue
@@ -49,68 +49,70 @@
         <div class="ui divided items">
           <div v-for="project in projects" :key="project.slug" class="item">
             <!-- {% if permissions|lookup:project.slug %} -->
-            <div class="ui tiny image">
-              <img
-                v-if="project.thumbnail"
-                class="ui small image"
-                :src="
-                  project.thumbnail.includes('default')
-                    ? require('@/assets/img/default.png')
-                    : DJANGO_BASE_URL + project.thumbnail + refreshId()
-                "
-                height="200"
-              />
-            </div>
-            <div class="middle aligned content">
-              <router-link
-                :to="{
-                  name: 'project_detail',
-                  params: { slug: project.slug },
-                }"
-                class="header"
-                >{{ project.title }}</router-link
-              >
-              <div class="description">
-                <p>{{ project.description }}</p>
+            <div v-frag v-if="user_permissions[project.slug].can_view_project">
+              <div class="ui tiny image">
+                <img
+                  v-if="project.thumbnail"
+                  class="ui small image"
+                  :src="
+                    project.thumbnail.includes('default')
+                      ? require('@/assets/img/default.png')
+                      : DJANGO_BASE_URL + project.thumbnail + refreshId()
+                  "
+                  height="200"
+                />
               </div>
-              <div class="meta">
-                <span class="right floated"
-                  >Projet {{ project.moderation ? "" : "non" }} modéré</span
+              <div class="middle aligned content">
+                <router-link
+                  :to="{
+                    name: 'project_detail',
+                    params: { slug: project.slug },
+                  }"
+                  class="header"
+                  >{{ project.title }}</router-link
                 >
-                <span
-                  >Niveau d'autorisation requis :
-                  {{ project.access_level_pub_feature }}</span
-                ><br />
-                <span>
-                  Mon niveau d'autorisation :
-                  <span v-if="USER_LEVEL_PROJECTS && project">{{
-                    USER_LEVEL_PROJECTS[project.slug]
-                  }}</span>
-                  <span v-if="user && user.is_administrator">{{
-                    "+ Gestionnaire métier"
-                  }}</span>
-                </span>
-              </div>
-              <div class="meta">
-                <span
-                  class="right floated"
-                  :data-tooltip="`Projet créé le ${project.created_on}`"
-                >
-                  <i class="calendar icon"></i>&nbsp;{{ project.created_on }}
-                </span>
-                <span data-tooltip="Membres">
-                  {{ project.nb_contributors }}&nbsp;<i class="user icon"></i>
-                </span>
-                <span data-tooltip="Signalements">
-                  {{ project.nb_published_features }}&nbsp;<i
-                    class="map marker icon"
-                  ></i>
-                </span>
-                <span data-tooltip="Commentaires">
-                  {{ project.nb_published_features_comments }}&nbsp;<i
-                    class="comment icon"
-                  ></i>
-                </span>
+                <div class="description">
+                  <p>{{ project.description }}</p>
+                </div>
+                <div class="meta">
+                  <span class="right floated"
+                    >Projet {{ project.moderation ? "" : "non" }} modéré</span
+                  >
+                  <span
+                    >Niveau d'autorisation requis :
+                    {{ project.access_level_pub_feature }}</span
+                  ><br />
+                  <span>
+                    Mon niveau d'autorisation :
+                    <span v-if="USER_LEVEL_PROJECTS && project">{{
+                      USER_LEVEL_PROJECTS[project.slug]
+                    }}</span>
+                    <span v-if="user && user.is_administrator">{{
+                      "+ Gestionnaire métier"
+                    }}</span>
+                  </span>
+                </div>
+                <div class="meta">
+                  <span
+                    class="right floated"
+                    :data-tooltip="`Projet créé le ${project.created_on}`"
+                  >
+                    <i class="calendar icon"></i>&nbsp;{{ project.created_on }}
+                  </span>
+                  <span data-tooltip="Membres">
+                    {{ project.nb_contributors }}&nbsp;<i class="user icon"></i>
+                  </span>
+                  <span data-tooltip="Signalements">
+                    {{ project.nb_published_features }}&nbsp;<i
+                      class="map marker icon"
+                    ></i>
+                  </span>
+                  <span data-tooltip="Commentaires">
+                    {{ project.nb_published_features_comments }}&nbsp;<i
+                      class="comment icon"
+                    ></i>
+                  </span>
+                </div>
               </div>
             </div>
           </div>
@@ -287,7 +289,12 @@ export default {
 
   computed: {
     // todo : filter projects to user
-    ...mapState(["user", "projects", "USER_LEVEL_PROJECTS"]),
+    ...mapState([
+      "user",
+      "projects",
+      "USER_LEVEL_PROJECTS",
+      "user_permissions",
+    ]),
     DJANGO_BASE_URL: () => process.env.VUE_APP_DJANGO_BASE,
     userFullname: function () {
       if (this.user.first_name || this.user.last_name)
diff --git a/src/views/feature/Feature_detail.vue b/src/views/feature/Feature_detail.vue
index 8b2c516d33814f65220cc0b7a795a4c281fc5060..e24f5574b2dc64d6cdfa7a363cb68eb4b8fbf7b5 100644
--- a/src/views/feature/Feature_detail.vue
+++ b/src/views/feature/Feature_detail.vue
@@ -6,8 +6,8 @@
           <div class="content">
             {{ feature.title || feature.feature_id }}
             <div class="ui icon right floated compact buttons">
-              <!-- {% if permissions|lookup:'can_create_feature' %} -->
               <router-link
+                v-if="permissions.can_create_feature"
                 :to="{
                   name: 'ajouter-signalement',
                   params: { slug_type_signal: $route.params.slug_type_signal },
@@ -18,8 +18,8 @@
               >
                 <i class="plus fitted icon"></i>
               </router-link>
-              <!-- {% endif %} {% if permissions|lookup:'can_update_feature' %} -->
               <router-link
+                v-if="permissions.can_update_feature"
                 :to="{
                   name: 'editer-signalement',
                   params: {
@@ -31,20 +31,18 @@
               >
                 <i class="inverted grey pencil alternate icon"></i>
               </router-link>
-              <!-- {% endif %} {% if permissions|lookup:'can_delete_feature' %} -->
               <a
+                v-if="permissions.can_delete_feature"
                 @click="isCanceling = true"
                 id="feature-delete"
                 class="ui button button-hover-red"
               >
                 <i class="inverted grey trash alternate icon"></i>
               </a>
-              <!-- {% endif %} -->
             </div>
             <div class="ui hidden divider"></div>
             <div class="sub header">
               {{ feature.description }}
-              <!--  | linebreaks -->
             </div>
           </div>
         </h1>
@@ -235,17 +233,15 @@
                   </div>
                   <div class="extra text">
                     {{ event.related_comment.comment }}
-                    <div v-frag v-if="event.related_comment.attachments">
-                      <div
-                        v-frag
-                        v-for="att in event.related_comment.attachments"
-                        :key="att.title"
+                    <div v-frag v-if="event.related_comment.attachment">
+                      <br /><a
+                        :href="
+                          DJANGO_BASE_URL + event.related_comment.attachment.url
+                        "
+                        tarrget="_blank"
+                        ><i class="paperclip fitted icon"></i>
+                        {{ event.related_comment.attachment.title }}</a
                       >
-                        <br /><a :href="att.url" tarrget="_blank"
-                          ><i class="paperclip fitted icon"></i>
-                          {{ att.title }}</a
-                        >
-                      </div>
                     </div>
                   </div>
                 </div>
@@ -265,23 +261,13 @@
           </div>
         </div>
 
-        <!-- {% if permissions|lookup:'can_create_feature' %} -->
-        <div class="ui segment">
+        <div v-if="permissions.can_create_feature" class="ui segment">
           <form
             id="form-comment"
             class="ui form"
             method="POST"
             enctype="multipart/form-data"
           >
-            <!-- <div
-              v-if="comment_form.non_field_errors"
-              class="alert alert-danger"
-              role="alert"
-            >
-              <span v-for="error in comment_form.non_field_errors" :key="error">
-                {{ error }}
-              </span>
-            </div> -->
             <div class="required field">
               <label :for="comment_form.comment.id_for_label"
                 >Ajouter un commentaire</label
@@ -312,7 +298,6 @@
                   id="attachment_file"
                   @change="getAttachmentFileData($event)"
                 />
-                <!-- {{ comment_form.attachment_file.errors }} -->
               </div>
               <div class="field">
                 <input
@@ -374,7 +359,7 @@
 
 <script>
 import frag from "vue-frag";
-import { mapState } from "vuex";
+import { mapGetters, mapState } from "vuex";
 import { mapUtil } from "@/assets/js/map-util.js";
 import featureAPI from "@/services/feature-api";
 const axios = require("axios");
@@ -416,6 +401,7 @@ export default {
 
   computed: {
     ...mapState(["user"]),
+    ...mapGetters(["permissions"]),
     ...mapState("feature", ["linked_features"]),
     DJANGO_BASE_URL: function () {
       return this.$store.state.configuration.VUE_APP_DJANGO_BASE;
@@ -459,12 +445,27 @@ export default {
       this.comment_form.attachment_file.value = shortName;
       this.comment_form.title.value = shortName;
     },
+    goBackToProject(message) {
+      this.$router.push({
+        name: "project_detail",
+        params: {
+          slug: this.$store.state.project_slug,
+          message,
+        },
+      });
+    },
 
     deleteFeature() {
       this.$store.dispatch(
         "feature/DELETE_FEATURE",
-        this.$route.params.slug_signal
-      );
+        this.feature.feature_id
+      )
+      .then(() => {
+        this.$store.dispatch(
+          "feature/GET_PROJECT_FEATURES"
+        )
+        this.goBackToProject();
+      });
     },
 
     initMap() {
@@ -539,6 +540,12 @@ export default {
         });
     },
 
+    getFeatureEvents() {
+      featureAPI
+        .getFeatureEvents(this.$route.params.slug_signal)
+        .then((data) => (this.events = data));
+    },
+
     getFeatureAttachments() {
       featureAPI
         .getFeatureAttachments(this.$route.params.slug_signal)
@@ -562,7 +569,7 @@ export default {
       "feature_type/SET_CURRENT_FEATURE_TYPE_SLUG",
       this.$route.params.slug_type_signal
     );
-
+    this.getFeatureEvents();
     this.getFeatureAttachments();
     this.getLinkedFeatures();
   },
diff --git a/src/views/feature/Feature_edit.vue b/src/views/feature/Feature_edit.vue
index 892a1e914c6bef03326823e1dc10b3e8606cee0e..da49900b25a1c4df3df16735e001afe25307738a 100644
--- a/src/views/feature/Feature_edit.vue
+++ b/src/views/feature/Feature_edit.vue
@@ -1,5 +1,6 @@
 <template>
   <div v-frag>
+    <script type="application/javascript" :src="baseUrl+'/resources/leaflet-control-geocoder-1.13.0/Control.Geocoder.js'"></script>
     <div class="fourteen wide column">
       <h1 v-if="feature && currentRouteName === 'editer-signalement'">
         Mise à jour du signalement "{{ feature.title || feature.feature_id }}"
@@ -41,7 +42,7 @@
               form.status.label
             }}</label>
             <Dropdown
-              :options="statusChoices"
+              :options="statusChoicesFilter"
               :selected="selected_status.name"
               :selection.sync="selected_status"
             />
@@ -226,7 +227,7 @@
 
 <script>
 import frag from "vue-frag";
-import { mapGetters, mapState } from "vuex";
+import { mapState } from "vuex";
 import FeatureAttachmentForm from "@/components/feature/FeatureAttachmentForm";
 import FeatureLinkedForm from "@/components/feature/FeatureLinkedForm";
 import FeatureExtraForm from "@/components/feature/FeatureExtraForm";
@@ -264,6 +265,8 @@ export default {
   data() {
     return {
       map: null,
+      feature_type:null,
+      baseUrl:this.$store.state.configuration.BASE_URL,
       file: null,
       showGeoRef: false,
       showGeoPositionBtn: true,
@@ -271,13 +274,24 @@ export default {
       erreurUploadMessage: null,
       attachmentDataKey: 0,
       linkedDataKey: 0,
+      statusChoicesFilter:[],
       statusChoices: [
         {
           name: "Brouillon",
           value: "draft",
         },
-        { name: "Publié", value: "published" },
-        { name: "Archivé", value: "archived" },
+         { 
+          name: "Publié",
+          value: "published"
+        },
+        { 
+          name: "Archivé",
+          value: "archived"
+        },
+        { 
+          name: "En attente de publication",
+          value: "pending" 
+        },
       ],
       form: {
         title: {
@@ -316,7 +330,7 @@ export default {
   },
 
   computed: {
-    ...mapState(["project"]),
+    // ...mapState(["project"]),
     ...mapState("map", ["basemaps"]),
     ...mapState("feature", [
       "attachmentFormset",
@@ -325,8 +339,6 @@ export default {
       "extra_form",
       "linked_features",
     ]),
-    ...mapGetters("feature_type", ["feature_type"]),
-
     field_title() {
       if (this.feature_type) {
         if (this.feature_type.title_optional) {
@@ -358,11 +370,6 @@ export default {
   },
 
   watch: {
-    feature_type() {
-      this.onFeatureTypeLoaded();
-      this.initExtraForms();
-    },
-
     feature(newValue) {
       if (this.$route.name === "editer-signalement") {
         this.initForm();
@@ -372,6 +379,20 @@ export default {
   },
 
   methods: {
+    makeStatusChoicesFilter(){
+      let newStatusChoices = this.statusChoices
+      if (this.project){
+        if (!this.project.moderation){
+          newStatusChoices = []
+          this.statusChoices.forEach(function(status) {
+            if (status.value !== 'pending') {
+              newStatusChoices.push(status)
+            }
+          });
+        }
+      }
+      this.statusChoicesFilter =  newStatusChoices
+    },
     initForm() {
       if (this.currentRouteName === "editer-signalement") {
         for (let key in this.feature) {
@@ -430,12 +451,30 @@ export default {
             "Content-Type": "multipart/form-data",
           },
         })
-        .then(function () {
-          console.log("SUCCESS!!");
+        .then(function (response) {
+          console.log("SUCCESS!!",response.data);
+          if(response.data.geom.indexOf('POINT')>=0){
+            let regexp=/POINT\s\((.*)\s(.*)\)/;
+            var arr = regexp.exec(response.data.geom);
+           
+            let json={ "type": "Feature",
+              "geometry": {
+                "type": "Point",
+                "coordinates": [arr[1], arr[2]]
+              },
+              "properties": {
+              }
+            };
+            self.updateMap(self.map, json)
+            self.updateGeomField(json)
+            // Set Attachment
+            //self.addAttachment(self.file)
+          }
+        
         })
-        .catch(function () {
+        .catch(function (response) {
           console.log("FAILURE!!");
-          self.erreurUploadMessage = "FAILURE!!";
+          self.erreurUploadMessage = response.data.message;
         });
     },
 
@@ -552,16 +591,6 @@ export default {
       return isValid;
     },
 
-    goBackToProject(message) {
-      this.$router.push({
-        name: "project_detail",
-        params: {
-          slug: this.$store.state.project_slug,
-          message,
-        },
-      });
-    },
-
     postForm() {
       let is_valid = true;
       if (!this.feature_type.title_optional) {
@@ -792,8 +821,6 @@ export default {
     },
 
     initMap() {
-      //console.log(drawnItems);
-      //console.log(configuration);
       var mapDefaultViewCenter =
         this.$store.state.configuration.DEFAULT_MAP_VIEW.center;
       var mapDefaultViewZoom =
@@ -864,8 +891,10 @@ export default {
 
   created() {
     if (!this.project) {
-      this.$store.dispatch("GET_PROJECT_INFO", this.$route.params.slug);
+      this.project = this.$store.state.projects.find((project) => project.slug === this.$store.state.project_slug);
+      this.makeStatusChoicesFilter();
     }
+
     this.$store.commit(
       "feature_type/SET_CURRENT_FEATURE_TYPE_SLUG",
       this.$route.params.slug_type_signal
@@ -882,8 +911,25 @@ export default {
   },
 
   mounted() {
-    this.initForm();
-    this.initMap();
+    let ftSlug=this.$route.params.slug_type_signal;
+    this.$store.dispatch("GET_PROJECT_INFO", this.$route.params.slug).then(data=>{
+        console.log(data)
+        this.initForm();
+        this.initMap();
+        this.feature_type=this.$store.state.feature_type.feature_types.find(
+                    (el) => el.slug === ftSlug
+                  );
+        this.onFeatureTypeLoaded();
+        this.initExtraForms();
+
+        setTimeout(
+          function () {
+            mapUtil.addGeocoders(this.$store.state.configuration);
+          }.bind(this), 1000);
+      })
+    
+
+    
   },
 };
 </script>
diff --git a/src/views/feature/Feature_list.vue b/src/views/feature/Feature_list.vue
index 8a2764cc2e69f5e25edc37309d966c198239711d..ad790844bbaefd7005a43b0484d01e1c94874490 100644
--- a/src/views/feature/Feature_list.vue
+++ b/src/views/feature/Feature_list.vue
@@ -1,11 +1,21 @@
 <template>
   <div class="fourteen wide column">
-    <script type="application/javascript" :src="baseUrl+'/resources/leaflet-control-geocoder-1.13.0/Control.Geocoder.js'"></script>
+    <script
+      type="application/javascript"
+      :src="
+        baseUrl +
+        '/resources/leaflet-control-geocoder-1.13.0/Control.Geocoder.js'
+      "
+    ></script>
     <div class="feature-list-container ui grid">
+      
       <div class="four wide column">
         <h1>Signalements</h1>
       </div>
       <div class="twelve wide column">
+        <div class="ui  dimmer" :class="[ { active: featureLoading }]">
+          <div class="ui large text loader">Chargement</div>
+        </div>
         <div class="ui secondary menu">
           <a
             @click="showMap = true"
@@ -28,11 +38,11 @@
               }}
             </h4>
           </div>
-          <!-- {% if project and feature_types and
-          permissions|lookup:'can_create_feature' %} -->
-          <!-- v-if="project && feature_types && permissions" -->
-          <!-- //Todo: add permissions -->
-          <div v-if="project && feature_types" class="item right">
+
+          <div
+            v-if="project && feature_types && permissions.can_create_feature"
+            class="item right"
+          >
             <div
               @click="showAddFeature = !showAddFeature"
               class="
@@ -69,28 +79,17 @@
                 </div>
               </div>
             </div>
-            
+
             <div v-if="project && feature_types" class="item right">
-            <div
-              
-              v-if="checkedFeatures.length"
-              class="
-                ui
-                top
-                center
-                pointing
-                compact
-                button button-hover-red
-              "
-              data-tooltip="Effacer tous les types de signalements sélectionnés"
-              data-position="left center"
-              data-variation="mini"
+              <div
+                v-if="checkedFeatures.length"
+                class="ui top center pointing compact button button-hover-red"
+                data-tooltip="Effacer tous les types de signalements sélectionnés"
+                data-position="left center"
+                data-variation="mini"
               >
-              <i
-                class="grey trash icon"
-                @click="modalAllDelete()"
-                ></i>
-            </div>
+                <i class="grey trash icon" @click="modalAllDelete()"></i>
+              </div>
             </div>
           </div>
         </div>
@@ -124,7 +123,12 @@
         <div class="ui icon input">
           <i class="search icon"></i>
           <div class="ui action input">
-            <input type="text" name="title" v-model="form.title" @input="onFilterChange()" />
+            <input
+              type="text"
+              name="title"
+              v-model="form.title"
+              @input="onFilterChange()"
+            />
             <button
               type="button"
               class="ui teal icon button"
@@ -143,44 +147,86 @@
 
     <div v-show="showMap" class="ui tab active map-container" data-tab="map">
       <div id="map"></div>
-      <SidebarLayers v-if="baseMaps && map"/>
+      <SidebarLayers v-if="baseMaps && map" />
     </div>
 
     <div v-show="!showMap" data-tab="list" class="dataTables_wrapper no-footer">
       <table id="table-features" class="ui compact table">
         <thead>
           <tr>
+            <th class="center"></th>
+
             <th class="center">
-              
+              Statut
+              <i
+                :class="{
+                  down: isSortedAsc('statut'),
+                  up: isSortedDesc('statut'),
+                }"
+                class="icon sort"
+                @click="changeSort('statut')"
+              />
+            </th>
+            <th class="center">
+              Type
+              <i
+                :class="{ down: isSortedAsc('type'), up: isSortedDesc('type') }"
+                class="icon sort"
+                @click="changeSort('type')"
+              />
+            </th>
+            <th class="center">
+              Nom
+              <i
+                :class="{ down: isSortedAsc('nom'), up: isSortedDesc('nom') }"
+                class="icon sort"
+                @click="changeSort('nom')"
+              />
+            </th>
+            <th class="center">
+              Dernière modification
+              <i
+                :class="{
+                  down: isSortedAsc('updated_on'),
+                  up: isSortedDesc('updated_on'),
+                }"
+                class="icon sort"
+                @click="changeSort('updated_on')"
+              />
+            </th>
+            <th class="center" v-if="user">
+              Auteur
+              <i
+                :class="{
+                  down: isSortedAsc('display_creator'),
+                  up: isSortedDesc('display_creator'),
+                }"
+                class="icon sort"
+                @click="changeSort('display_creator')"
+              />
             </th>
-
-            <th class="center">Statut <i :class="{ down: isSortedAsc('statut'),up:isSortedDesc('statut') }" class="icon sort" @click="changeSort('statut')"/></th>
-            <th class="center">Type <i :class="{ down: isSortedAsc('type'),up:isSortedDesc('type') }" class="icon sort" @click="changeSort('type')"/></th>
-            <th class="center">Nom <i :class="{ down: isSortedAsc('nom'),up:isSortedDesc('nom') }" class="icon sort" @click="changeSort('nom')"/></th>
-            <th class="center">Dernière modification <i :class="{ down: isSortedAsc('updated_on'),up:isSortedDesc('updated_on') }" class="icon sort" @click="changeSort('updated_on')"/></th>
-            <th class="center" v-if="user" >Auteur <i :class="{ down: isSortedAsc('display_creator'),up:isSortedDesc('display_creator') }" class="icon sort" @click="changeSort('display_creator')"/></th>
           </tr>
         </thead>
         <tbody>
-          <tr
-            v-for="(feature, index) in getPaginatedFeatures()"
-            :key="index"
-          >
+          <tr v-for="(feature, index) in getPaginatedFeatures()" :key="index">
             <td class="center">
-                <div class="ui checkbox">
-                  <input 
-                    type="checkbox" 
-                    :id="feature.id" 
-                    :value="feature.id"  
-                    v-model="checkedFeatures"
-                    :checked="checkedFeatures[feature.id]"
-                    >
-                    <label></label>
-                  </div>
-              </td>
+              <div class="ui checkbox">
+                <input
+                  type="checkbox"
+                  :id="feature.id"
+                  :value="feature.id"
+                  v-model="checkedFeatures"
+                  :checked="checkedFeatures[feature.id]"
+                />
+                <label></label>
+              </div>
+            </td>
 
             <td class="center">
-              <div v-if="feature.properties.status.value == 'archived'" data-tooltip="Archivé">
+              <div
+                v-if="feature.properties.status.value == 'archived'"
+                data-tooltip="Archivé"
+              >
                 <i class="grey archive icon"></i>
               </div>
               <div
@@ -206,7 +252,9 @@
               <router-link
                 :to="{
                   name: 'details-type-signalement',
-                  params: { feature_type_slug: feature.properties.feature_type.title },
+                  params: {
+                    feature_type_slug: feature.properties.feature_type.title,
+                  },
                 }"
               >
                 {{ feature.properties.feature_type.title }}
@@ -221,7 +269,7 @@
                     slug_signal: feature.properties.slug || feature.id,
                   },
                 }"
-                >{{ getFeatureDisplayName(feature)}}</router-link
+                >{{ getFeatureDisplayName(feature) }}</router-link
               >
             </td>
             <td class="center">
@@ -229,7 +277,7 @@
               {{ feature.properties.updated_on }}
             </td>
             <td  class="center" v-if="user">
-              {{ feature.properties.display_creator }}
+              {{ feature.properties.creator.username }}
             </td>
           </tr>
           <tr v-if="getFilteredFeatures().length === 0" class="odd">
@@ -239,7 +287,7 @@
           </tr>
         </tbody>
       </table>
-       <div
+      <div
         class="dataTables_info"
         id="table-features_info"
         role="status"
@@ -247,11 +295,12 @@
       >
         Affichage de l'élément {{ pagination.start + 1 }} à
         {{ pagination.end + 1 }} sur {{ getFilteredFeatures().length }} éléments
-      </div> 
+      </div>
       <div
         class="dataTables_paginate paging_simple_numbers"
         id="table-features_paginate"
-      > <a
+      >
+        <a
           @click="toPreviousPage"
           class="paginate_button previous disabled"
           aria-controls="table-features"
@@ -270,24 +319,23 @@
             >{{index}}</a
           > </span>
        <span class="ellipsis">…</span> -->
-       <a
-            class="paginate_button next"
-            aria-controls="table-features"
-            data-dt-idx="7"
-            tabindex="0"
-            id="table-features_next"
-            @click="toNextPage"
-            >Suivant</a
-          > 
-      
-      </div> 
+        <a
+          class="paginate_button next"
+          aria-controls="table-features"
+          data-dt-idx="7"
+          tabindex="0"
+          id="table-features_next"
+          @click="toNextPage"
+          >Suivant</a
+        >
+      </div>
     </div>
     <!-- MODAL ALL DELETE FEATURE TYPE -->
     <div
       v-if="modalAllDeleteOpen"
       class="ui dimmer modals page transition visible active"
       style="display: flex !important"
-      >
+    >
       <div
         :class="[
           'ui mini modal subscription',
@@ -297,23 +345,18 @@
         <i @click="modalAllDeleteOpen = false" class="close icon"></i>
         <div class="ui icon header">
           <i class="trash alternate icon"></i>
-          Êtes-vous sûr de vouloir effacer 
-          <span v-if="checkedFeatures.length == 1"> 
-            un signalement ?
-          </span>
-          <span v-else> 
-            ces {{checkedFeatures.length}} signalements ?
-          </span>
+          Êtes-vous sûr de vouloir effacer
+          <span v-if="checkedFeatures.length == 1"> un signalement ? </span>
+          <span v-else> ces {{ checkedFeatures.length }} signalements ? </span>
         </div>
         <div class="actions">
-          
-            <button
-              @click="deleteAllFeatureSelection()"
-              type="button"
-              class="ui red compact fluid button"
-            >
-              Confirmer la suppression
-            </button>
+          <button
+            @click="deleteAllFeatureSelection()"
+            type="button"
+            class="ui red compact fluid button"
+          >
+            Confirmer la suppression
+          </button>
         </div>
       </div>
     </div>
@@ -322,8 +365,6 @@
 
 <script>
 import { mapGetters, mapState } from "vuex";
-
-import L from "leaflet";
 import { mapUtil } from "@/assets/js/map-util.js";
 import SidebarLayers from "@/components/map-layers/SidebarLayers";
 import Dropdown from "@/components/Dropdown.vue";
@@ -373,15 +414,16 @@ export default {
         title: null,
       },
       pagination: {
-        pagesize:15,
+        pagesize: 15,
         start: 0,
         end: 14,
       },
-      sort:{
-        column:'',
-        ascending:true
+      sort: {
+        column: "",
+        ascending: true,
       },
       geojsonFeatures:[],
+      featureLoading:false,
       filterStatus:null,
       filterType:null,
       baseUrl:this.$store.state.configuration.BASE_URL,
@@ -395,27 +437,25 @@ export default {
   },
 
   computed: {
-    ...mapGetters(["project"]),
+    ...mapGetters(["project", "permissions"]),
     ...mapState(["user"]),
     ...mapState("feature", ["features"]),
     ...mapState("feature_type", ["feature_types"]),
-    
-    baseMaps(){
+
+    baseMaps() {
       return this.$store.state.map.basemaps;
     },
-    
   },
   methods: {
-    modalAllDelete(){
+    modalAllDelete() {
       return (this.modalAllDeleteOpen = !this.modalAllDeleteOpen);
     },
-    deleteFeature(feature){
-      const url=`${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}features/${feature.feature_id}`;
+    deleteFeature(feature) {
+      const url = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}features/${feature.feature_id}`;
       axios
-        .delete(url, {
-        })
+        .delete(url, {})
         .then(() => {
-          if(!this.modalAllDeleteOpen){
+          if (!this.modalAllDeleteOpen) {
             this.$router.go();
           }
         })
@@ -423,93 +463,91 @@ export default {
           return false;
         });
     },
-    deleteAllFeatureSelection(){
-      let feature = {}
-      this.checkedFeatures.forEach(feature_id => {
-        feature = {'feature_id': feature_id};
+    deleteAllFeatureSelection() {
+      let feature = {};
+      this.checkedFeatures.forEach((feature_id) => {
+        feature = { feature_id: feature_id };
         this.deleteFeature(feature);
       });
       this.modalAllDelete();
     },
-    getFeatureDisplayName(feature){
+    getFeatureDisplayName(feature) {
       return feature.properties.title || feature.id;
     },
     getPaginatedFeatures() {
-      let filterdFeatures=[...this.getFilteredFeatures()];
+      let filterdFeatures = [...this.getFilteredFeatures()];
       // Ajout du tri
-      if(this.sort.column!=''){
-        filterdFeatures=filterdFeatures.sort((a,b)=>{
-            let aProp=this.getFeatureDisplayName(a);
-            let bProp=this.getFeatureDisplayName(b);
-            if(this.sort.column=='statut') {
-              aProp=a.properties.status.value;
-              bProp=b.properties.status.value;
-            }
-            else if(this.sort.column=='type') {
-              aProp=a.properties.feature_type.title;
-              bProp=b.properties.feature_type.title;
-            }
-            else if(this.sort.column=='updated_on') {
-              aProp=a.properties.updated_on;
-              bProp=b.properties.updated_on;
+      if (this.sort.column != "") {
+        filterdFeatures = filterdFeatures.sort((a, b) => {
+          let aProp = this.getFeatureDisplayName(a);
+          let bProp = this.getFeatureDisplayName(b);
+          if (this.sort.column == "statut") {
+            aProp = a.properties.status.value;
+            bProp = b.properties.status.value;
+          } else if (this.sort.column == "type") {
+            aProp = a.properties.feature_type.title;
+            bProp = b.properties.feature_type.title;
+          } else if (this.sort.column == "updated_on") {
+            aProp = a.properties.updated_on;
+            bProp = b.properties.updated_on;
+          } else if (this.sort.column == "display_creator") {
+            aProp = a.properties.display_creator;
+            bProp = b.properties.display_creator;
+          }
+
+          //ascending
+          if (this.sort.ascending) {
+            if (aProp < bProp) {
+              return -1;
             }
-            else if(this.sort.column=='display_creator') {
-              aProp=a.properties.display_creator;
-              bProp=b.properties.display_creator;
+            if (aProp > bProp) {
+              return 1;
             }
-            
-            //ascending
-            if(this.sort.ascending){
-              if(aProp < bProp) { return -1; }
-              if(aProp > bProp) { return 1; }
-              return 0;
+            return 0;
+          } else {
+            //descending
+            if (aProp < bProp) {
+              return 1;
             }
-            else{
-              //descending
-              if(aProp < bProp) { return 1; }
-              if(aProp > bProp) { return -1; }
-              return 0;
+            if (aProp > bProp) {
+              return -1;
             }
-            
-            
-          })
+            return 0;
+          }
+        });
       }
 
-      return filterdFeatures.slice(
-        this.pagination.start,
-        this.pagination.end
-      );
+      return filterdFeatures.slice(this.pagination.start, this.pagination.end);
     },
-    isSortedAsc(column){
-      return this.sort.column==column && this.sort.ascending;
+    isSortedAsc(column) {
+      return this.sort.column == column && this.sort.ascending;
     },
-    isSortedDesc(column){
-      return this.sort.column==column && !this.sort.ascending;
+    isSortedDesc(column) {
+      return this.sort.column == column && !this.sort.ascending;
     },
-    changeSort(column){
-      if(this.sort.column==column){
-         //changer order
-          this.sort.ascending=!this.sort.ascending;
-      }else{
-        this.sort.column=column;
-        this.sort.ascending=true;
+    changeSort(column) {
+      if (this.sort.column == column) {
+        //changer order
+        this.sort.ascending = !this.sort.ascending;
+      } else {
+        this.sort.column = column;
+        this.sort.ascending = true;
       }
-      
     },
-    onFilterStatusChange(newvalue){
-      this.filterStatus=null;
-      if(newvalue){
-          console.log("filter change",newvalue.value);
-          this.filterStatus=newvalue.value;
+    onFilterStatusChange(newvalue) {
+      this.filterStatus = null;
+      if (newvalue) {
+        console.log("filter change", newvalue.value);
+        this.filterStatus = newvalue.value;
       }
 
       this.onFilterChange();
     },
-    onFilterTypeChange(newvalue){
-      this.filterType=null;
-      if(newvalue){
-          console.log("filter change",newvalue);
-          this.filterType=newvalue;
+    onFilterTypeChange(newvalue) {
+      this.filterType = null;
+      if (newvalue) {
+        console.log("filter change", newvalue);
+        this.filterType = newvalue;
       }
 
       this.onFilterChange();
@@ -525,7 +563,7 @@ export default {
     },
     getFilteredFeatures() {
       let results = this.geojsonFeatures;
-       if (this.filterType) {
+      if (this.filterType) {
         results = results.filter(
           (el) => el.properties.feature_type.title === this.filterType
         );
@@ -544,15 +582,14 @@ export default {
               .includes(this.form.title.toLowerCase());
           } else
             return el.id.toLowerCase().includes(this.form.title.toLowerCase());
-        }
-          
-          
-        );
+        });
       }
       return results;
     },
-    getNbPages(){
-      return Math.round(this.getFilteredFeatures().length/this.pagination.pagesize);
+    getNbPages() {
+      return Math.round(
+        this.getFilteredFeatures().length / this.pagination.pagesize
+      );
     },
     toPreviousPage() {
       if (this.pagination.start > 0) {
@@ -566,9 +603,8 @@ export default {
         this.pagination.end += this.pagination.pagesize;
       }
     },
-    loadFeatures(features){
+    loadFeatures(features) {
       this.geojsonFeatures = features;
-      console.log(this.geojsonFeatures);
       const urlParams = new URLSearchParams(window.location.search);
       const featureType = urlParams.get("feature_type");
       const featureStatus = urlParams.get("status");
@@ -586,40 +622,11 @@ export default {
         mapUtil.getMap().fitBounds(this.featureGroup.getBounds());
       }
       this.form.type.choices = [
-      //* converting Set to an Array with spread "..."
-      ...new Set(this.geojsonFeatures.map((el) => el.properties.feature_type.title)), //* use Set to eliminate duplicate values
-    ];
-    },
-    addGeocoders(){
-      let geocoder;
-
-      // Get the settings.py variable SELECTED_GEOCODER_PROVIDER. This way avoids XCC attacks
-      const geocoderLabel =
-        this.$store.state.configuration.SELECTED_GEOCODER.PROVIDER;
-      if (geocoderLabel) {
-        const LIMIT_RESULTS = 5;
-        if (
-          geocoderLabel ===
-          this.$store.state.configuration.GEOCODER_PROVIDERS.ADDOK
-        ) {
-          geocoder = L.Control.Geocoder.addok({ limit: LIMIT_RESULTS });
-        } else if (
-          geocoderLabel ===
-          this.$store.state.configuration.GEOCODER_PROVIDERS.PHOTON
-        ) {
-          geocoder = L.Control.Geocoder.photon();
-        } else if (
-          geocoderLabel ===
-          this.$store.state.configuration.GEOCODER_PROVIDERS.NOMINATIM
-        ) {
-          geocoder = L.Control.Geocoder.nominatim();
-        }
-
-        L.Control.geocoder({
-          placeholder: "Chercher une adresse...",
-          geocoder: geocoder,
-        }).addTo(this.map);
-      }
+        //* converting Set to an Array with spread "..."
+        ...new Set(
+          this.geojsonFeatures.map((el) => el.properties.feature_type.title)
+        ), //* use Set to eliminate duplicate values
+      ];
     },
   },
 
@@ -630,23 +637,22 @@ export default {
     }
   },
   mounted() {
-
-
-
-    this.zoom = this.$route.query.zoom||'';
-    this.lat = this.$route.query.lat||'';
-    this.lng = this.$route.query.lng||'';
-    var mapDefaultViewCenter = this.$store.state.configuration.DEFAULT_MAP_VIEW.center;
-    var mapDefaultViewZoom = this.$store.state.configuration.DEFAULT_MAP_VIEW.zoom;
-
-    this.map=mapUtil.createMap({
-      zoom:this.zoom,
-      lat:this.lat,
-      lng:this.lng,
+    this.zoom = this.$route.query.zoom || "";
+    this.lat = this.$route.query.lat || "";
+    this.lng = this.$route.query.lng || "";
+    var mapDefaultViewCenter =
+      this.$store.state.configuration.DEFAULT_MAP_VIEW.center;
+    var mapDefaultViewZoom =
+      this.$store.state.configuration.DEFAULT_MAP_VIEW.zoom;
+
+    this.map = mapUtil.createMap({
+      zoom: this.zoom,
+      lat: this.lat,
+      lng: this.lng,
       mapDefaultViewCenter,
       mapDefaultViewZoom,
     });
-    
+
     document.addEventListener("change-layers-order", (event) => {
       // Reverse is done because the first layer in order has to be added in the map in last.
       // Slice is done because reverse() changes the original array, so we make a copy first
@@ -654,29 +660,29 @@ export default {
     });
 
     // --------- End sidebar events ----------
-      console.log(this.$store.state.map.geojsonFeatures);
       if(this.$store.state.map.geojsonFeatures){
         this.loadFeatures(this.$store.state.map.geojsonFeatures);
       }
       else{
         const url=`${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.$route.params.slug}/feature/?output=geojson`;
+        this.featureLoading=true;
         axios.get(url)
           .then((response) => {
             this.loadFeatures(response.data.features);
+            this.featureLoading=false;
           })
           .catch((error) => {
+            this.featureLoading=false;
             throw error;
+            
           });
       }
 
-
     setTimeout(
       function () {
-        this.addGeocoders();
-      }.bind(this), 1000)
-
+        mapUtil.addGeocoders(this.$store.state.configuration);
+      }.bind(this), 1000);
 
-    
   },
 };
 </script>
@@ -692,7 +698,7 @@ export default {
   z-index: 1;
 }
 
-.center{
+.center {
   text-align: center !important;
 }
 
diff --git a/src/views/feature_type/Feature_type_detail.vue b/src/views/feature_type/Feature_type_detail.vue
index cd18f5ec2fa0f784d0cf5452bbaef8081649ba32..764d774b093e625b0703557700d1b0b7a049d793 100644
--- a/src/views/feature_type/Feature_type_detail.vue
+++ b/src/views/feature_type/Feature_type_detail.vue
@@ -29,7 +29,7 @@
         <div class="ui basic segment">
           <div class="ui horizontal tiny statistic">
             <div class="value">
-              {{ features.length }}
+              {{ feature_type_features.length }}
             </div>
             <div class="label">
               Signalement{{ features.length > 1 ? "s" : "" }}
@@ -53,9 +53,7 @@
       </div>
 
       <div class="ui bottom attached secondary segment">
-        <!-- // ToDo : gérer permissions -->
-        <!-- <div v-if="permissions.can_create_feature" class="ui styled accordion"> -->
-        <div class="ui styled accordion">
+        <div v-if="permissions.can_create_feature" class="ui styled accordion">
           <div
             @click="toggleShowImport"
             :class="['title', { active: showImport }]"
@@ -111,7 +109,6 @@
             >
               <i class="download icon"></i> Exporter
             </button>
-            <!-- // todo gérer export -->
           </div>
         </div>
       </div>
@@ -174,8 +171,8 @@
         <i class="right arrow icon"></i>
         Voir tous les signalements
       </router-link>
-      <!-- v-if="permissions.can_create_feature" -->
       <router-link
+        v-if="permissions.can_create_feature"
         :to="{
           name: 'ajouter-signalement',
           params: { slug_type_signal: structure.slug },
@@ -184,7 +181,7 @@
       >
         Ajouter un signalement
       </router-link>
-      <br /><!-- // ToDo : gérer permissions -->
+      <br />
     </div>
   </div>
 </template>
@@ -210,7 +207,7 @@ export default {
   },
 
   computed: {
-    ...mapGetters(["project"]),
+    ...mapGetters(["project", "permissions"]),
     ...mapState("feature", ["features"]),
     ...mapState("feature_type", ["feature_types", "importFeatureTypeData"]),
     structure: function () {
@@ -222,8 +219,15 @@ export default {
       }
       return null;
     },
+
+    feature_type_features: function () {
+      return this.features.filter(
+        (el) => el.feature_type.slug === this.$route.params.feature_type_slug
+      );
+    },
+
     lastFeatures: function () {
-      return this.features.slice(0, 5);
+      return this.feature_type_features.slice(0, 5);
     },
   },
 
@@ -250,7 +254,7 @@ export default {
     },
     exportFeatures() {
       const url = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.$route.params.slug}/feature-type/${this.$route.params.feature_type_slug}/export/`;
-      console.log(url)
+      console.log(url);
       window.open(url);
     },
   },
diff --git a/src/views/flatpages/Default.vue b/src/views/flatpages/Default.vue
index af38296848360fd63ff2959cb145688a120ce05a..9c8443814c424080936686fbc796b77fc955070d 100644
--- a/src/views/flatpages/Default.vue
+++ b/src/views/flatpages/Default.vue
@@ -1,7 +1,6 @@
 <template>
   <div v-if="flatpage" class="row">
     <div class="ten wide column">
-      {{ this.$route.params.url }}
       <h1>{{ flatpage.title }}</h1>
       <div v-html="flatpage.content"></div>
     </div>
@@ -9,13 +8,17 @@
 </template>
 
 <script>
+import { mapState } from "vuex";
+
 export default {
   name: "Default",
+
   computed: {
+    ...mapState(["staticPages"]),
     flatpage() {
-      if (this.$store.state.staticPages) {
-        return this.$store.state.staticPages.find(
-          (page) => page.url === this.$route.path
+      if (this.staticPages) {
+        return this.staticPages.find(
+          (page) => page.url === `/${this.$route.name}/`
         );
       }
       return null;
diff --git a/src/views/flatpages/with_right_menu.vue b/src/views/flatpages/with_right_menu.vue
index 645789602cf33c1172b03956d752edc0d29ed58f..c04a20b34a1990deba6f54b482f0eb40f0ec27c7 100644
--- a/src/views/flatpages/with_right_menu.vue
+++ b/src/views/flatpages/with_right_menu.vue
@@ -23,18 +23,23 @@
 </template>
 
 <script>
+import { mapState } from "vuex";
+
 export default {
   name: "With_right_menu",
+
   data() {
     return {
       sections: [],
     };
   },
+
   computed: {
+    ...mapState(["staticPages"]),
     flatpage() {
-      if (this.$store.state.staticPages) {
-        return this.$store.state.staticPages.find(
-          (page) => page.url === this.$route.path
+      if (this.staticPages) {
+        return this.staticPages.find(
+          (page) => page.url === `/${this.$route.name}/`
         );
       }
       return null;
diff --git a/src/views/project/Project_detail.vue b/src/views/project/Project_detail.vue
index 8bff78d9e0d9dbb71fe8672f0eeb4899fb0d4414..bff3fa9291819c0539257083011c7a90d960670e 100644
--- a/src/views/project/Project_detail.vue
+++ b/src/views/project/Project_detail.vue
@@ -9,6 +9,16 @@
           <p><i class="check icon"></i> {{ tempMessage }}</p>
         </div>
       </div>
+      <div id="message_info" class="fullwidth">
+        <div v-if="infoMessage" class="ui info message" style="text-align: left;">
+           <div class="header">
+              <i class="info circle icon"></i> Informations
+            </div>
+          <ul class="list">
+            {{ infoMessage }}
+           </ul>
+          </div>
+      </div>
 
       <div class="row">
         <div class="four wide middle aligned column">
@@ -37,8 +47,8 @@
             <div class="content">
               {{ project.title }}
               <div class="ui icon right floated compact buttons">
-                <!-- {% if permissions|lookup:'can_view_project' %} -->
                 <a
+                  v-if="permissions.can_view_project"
                   id="subscribe-button"
                   class="ui button button-hover-green"
                   data-tooltip="S'abonner au projet"
@@ -48,10 +58,8 @@
                 >
                   <i class="inverted grey envelope icon"></i>
                 </a>
-                <!-- {% endif %} {% if project and
-              permissions|lookup:'can_update_project' %} -->
                 <router-link
-                  v-if="user"
+                  v-if="permissions.can_update_project"
                   :to="{ name: 'project_edit', params: { slug: project.slug } }"
                   class="ui button button-hover-orange"
                   data-tooltip="Modifier le projet"
@@ -60,12 +68,10 @@
                 >
                   <i class="inverted grey pencil alternate icon"></i>
                 </router-link>
-                <!-- {% endif %} -->
               </div>
               <div class="ui hidden divider"></div>
               <div class="sub header">
                 {{ project.description }}
-                <!-- {{ project.description | linebreaks }} -->
               </div>
             </div>
           </h1>
@@ -74,7 +80,6 @@
 
       <div class="row">
         <div class="seven wide column">
-          <!--  // todo : Create endpoints for feature_types -->
           <div class="ui middle aligned divided list">
             <div
               v-for="(type, index) in feature_types"
@@ -82,7 +87,7 @@
               class="item"
             >
               <div class="middle aligned content">
-               <router-link
+                <router-link
                   :to="{
                     name: 'details-type-signalement',
                     params: { feature_type_slug: type.slug },
@@ -107,18 +112,18 @@
                 </router-link>
                 <!-- {% if project and feature_types and
               permissions|lookup:'can_create_feature' %} -->
-                <!-- // todo: add permissions.can_create_feature and type.is_editable -->
-                <!--  v-if="
+                <!-- // ? should we get type.is_editable ? -->
+                <!-- v-if="
                     project &&
                     permissions.can_create_feature &&
                     type.is_editable
                   " -->
                 <router-link
+                  v-if="project && permissions.can_create_feature"
                   :to="{
                     name: 'ajouter-signalement',
                     params: { slug_type_signal: type.slug },
                   }"
-                  v-if="project && permissions.can_create_feature"
                   class="
                     ui
                     compact
@@ -131,7 +136,7 @@
                   data-tooltip="Ajouter un signalement"
                   data-position="left center"
                   data-variation="mini"
-                  ><!-- // todo : adapt -->
+                >
                   <i class="ui plus icon"></i>
                 </router-link>
                 <router-link
@@ -152,7 +157,7 @@
                   data-tooltip="Dupliquer un type de signalement"
                   data-position="left center"
                   data-variation="mini"
-                  ><!-- // todo : adapt -->
+                >
                   <i class="inverted grey copy alternate icon"></i>
                 </router-link>
                 <router-link
@@ -183,9 +188,10 @@
               <i> Le projet ne contient pas encore de type de signalements. </i>
             </div>
           </div>
-          <!-- // todo: gérer permissions:  {% if project and permissions|lookup:'can_update_project' %} -->
+
           <div class="nouveau-type-signalement">
             <router-link
+              v-if="permissions.can_update_project"
               :to="{
                 name: 'ajouter-type-signalement',
                 params: { slug: project.slug },
@@ -329,7 +335,6 @@
                   </h4>
                 </div>
                 <div class="center aligned extra content">
-                  <!-- {{ project.archive_feature|default_if_none:"0" }} jours -->
                   {{ project.archive_feature }} jours
                 </div>
               </div>
@@ -343,7 +348,6 @@
                   </h4>
                 </div>
                 <div class="center aligned extra content">
-                  <!-- {{ project.delete_feature|default_if_none:"0" }} jours -->
                   {{ project.delete_feature }} jours
                 </div>
               </div>
@@ -389,7 +393,7 @@
         </div>
       </div>
     </div>
-    <span v-else-if="!permissions.can_view_project">
+    <span v-else>
       <i class="icon exclamation triangle"></i>
       <span
         >Vous ne disposez pas des droits nécessaires pour consulter ce
@@ -428,7 +432,6 @@
         </div>
       </div>
     </div>
-
   </div>
 </template>
 
@@ -437,7 +440,6 @@ import frag from "vue-frag";
 import { mapUtil } from "@/assets/js/map-util.js";
 import { mapGetters, mapState } from "vuex";
 import projectAPI from "@/services/project-api";
-//import addressAPI from '@/services/address-api';
 
 const axios = require("axios");
 
@@ -464,22 +466,18 @@ export default {
 
   data() {
     return {
+      infoMessage: '',
       geojsonImport: [],
       fileToImport: { name: "", size: 0 },
       slug: this.$route.params.slug,
       isModalOpen: false,
       is_suscriber: false,
-      permissions: {
-        // ! fake, should be replaced by api's data
-        can_view_project: true,
-        can_create_feature: true,
-      },
       tempMessage: null,
     };
   },
 
   computed: {
-    ...mapGetters(["project"]),
+    ...mapGetters(["project", "permissions"]),
     ...mapState("feature_type", ["feature_types"]),
     ...mapState("feature", ["features"]),
     ...mapState(["last_comments", "user"]),
@@ -530,18 +528,30 @@ export default {
           suscribe: !this.is_suscriber,
           projectSlug: this.$route.params.slug,
         })
-        .then((data) => (this.is_suscriber = data.is_suscriber));
+        .then((data) => {
+          this.is_suscriber = data.is_suscriber;
+          this.isModalOpen = false;
+          if (this.is_suscriber)
+            this.infoMessage = 'Vous êtes maintenant abonné aux notifications de ce projet.';
+          else
+            this.infoMessage = "Vous ne recevrez plus les notifications de ce projet.";
+          setTimeout(function(){ 
+            this.infoMessage = ''; 
+            }.bind(this), 3000);
+          });
     },
   },
   created() {
     this.$store.dispatch("GET_PROJECT_INFO", this.slug);
-    projectAPI
-      .getProjectSubscription({ projectSlug: this.$route.params.slug })
-      .then((data) => (this.is_suscriber = data.is_suscriber));
+    if (this.user) {
+      projectAPI
+        .getProjectSubscription({ projectSlug: this.$route.params.slug })
+        .then((data) => (this.is_suscriber = data.is_suscriber));
+    }
   },
 
   mounted() {
-    if (this.project) {
+    if (this.project && this.permissions.can_view_project) {
       this.$store.dispatch("map/INITIATE_MAP");
       const url = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.$route.params.slug}/feature/?output=geojson`;
       let self = this;
diff --git a/src/views/project/Project_edit.vue b/src/views/project/Project_edit.vue
index 72a6344c09054bf111b1fd2f44b4a4fe9b5e596c..8fefe1f87880bb0e53291585b512e651a6bd61eb 100644
--- a/src/views/project/Project_edit.vue
+++ b/src/views/project/Project_edit.vue
@@ -172,12 +172,11 @@ import Dropdown from "@/components/Dropdown.vue";
 
 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;
-  })('csrftoken');
-
+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;
+})("csrftoken");
 
 export default {
   name: "Project_edit",
@@ -284,30 +283,28 @@ export default {
 
     postProjectThumbnail(projectSlug) {
       //* send img to the backend when feature_type is created
-      if (this.fileToImport.size > 0) {
-        let formData = new FormData();
-        formData.append("file", this.fileToImport);
-        const url =
-          this.$store.state.configuration.VUE_APP_DJANGO_API_BASE +
-          "projects/" +
-          projectSlug +
-          "/thumbnail/";
-        return axios
-          .put(url, formData, {
-            headers: {
-              "Content-Type": "multipart/form-data",
-            },
-          })
-          .then((response) => {
-            if (response && response.status === 200) {
-              //dispatch("GET_IMPORTS", feature_type_slug); // ? Besoin de vérifier le statut de l'import ?
-              this.goBackNrefresh(projectSlug);
-            }
-          })
-          .catch((error) => {
-            throw error;
-          });
-      }
+      let formData = new FormData();
+      formData.append("file", this.fileToImport);
+      const url =
+        this.$store.state.configuration.VUE_APP_DJANGO_API_BASE +
+        "projects/" +
+        projectSlug +
+        "/thumbnail/";
+      return axios
+        .put(url, formData, {
+          headers: {
+            "Content-Type": "multipart/form-data",
+          },
+        })
+        .then((response) => {
+          if (response && response.status === 200) {
+            //dispatch("GET_IMPORTS", feature_type_slug); // ? Besoin de vérifier le statut de l'import ?
+            this.goBackNrefresh(projectSlug);
+          }
+        })
+        .catch((error) => {
+          throw error;
+        });
     },
 
     checkForm() {
@@ -331,8 +328,6 @@ export default {
 
     async postForm() {
       if (!this.checkForm()) return;
-      // todo: check form
-      //let url = `${configuration.VUE_APP_DJANGO_API_BASE}projects/`;
       const projectData = {
         title: this.form.title,
         description: this.form.description,
@@ -371,11 +366,12 @@ export default {
           )
           .then((response) => {
             if (response && response.status === 200) {
-              //* send thumbnail after feature_type was created
-              if (this.fileToImport)
+              //* send thumbnail after feature_type was updated
+              if (this.fileToImport.size > 0) {
                 this.postProjectThumbnail(this.project.slug);
-            } else {
-              this.goBackNrefresh(this.project.slug);
+              } else {
+                this.goBackNrefresh(this.project.slug);
+              }
             }
           })
           .catch((error) => {
diff --git a/src/views/project/Project_mapping.vue b/src/views/project/Project_mapping.vue
index f7a0b2ec7de6d78074f1a13137cc291484b3f194..0a94b5a82f1f41a2ff965afbc1bb64a88b867b04 100644
--- a/src/views/project/Project_mapping.vue
+++ b/src/views/project/Project_mapping.vue
@@ -21,7 +21,7 @@
         </a>
       </div>
 
-      <div class="ui">
+      <div v-if="basemaps" class="ui">
         <ProjectMappingBasemap
           v-for="basemap in basemaps"
           :key="basemap.id"
@@ -70,7 +70,11 @@ export default {
 
     saveChanges() {
       // ToDo : check if values are filled
-      this.$store.dispatch("map/SAVE_BASEMAPS", this.newBasemapIds);
+      this.$store.dispatch("map/SAVE_BASEMAPS", this.newBasemapIds)
+      .then((res) => {
+        console.log('res', res)
+      });
+      this.newBasemapIds = [];
     },
   },
 
diff --git a/src/views/project/Project_members.vue b/src/views/project/Project_members.vue
index 4ad7e25a33e03e953737276abc35048100cdc25c..4e88ca6367b4a5ada50ab7069aaf68c687968e35 100644
--- a/src/views/project/Project_members.vue
+++ b/src/views/project/Project_members.vue
@@ -9,7 +9,6 @@
       enctype="multipart/form-data"
       class="ui form"
     >
-      <!-- {{ formset.non_form_errors }} -->
       <table class="ui red table">
         <thead>
           <tr>
@@ -18,25 +17,23 @@
           </tr>
         </thead>
         <tbody>
-          <div v-frag v-for="member in projectMembers" :key="member.username">
-            <tr>
-              <td>
-                {{ member.last_name }} {{ member.first_name }}<br /><i>{{
-                  member.username
-                }}</i>
-              </td>
-              <td>
-                <div class="required field">
-                  <Dropdown
-                    :options="levelOptions"
-                    :selected="member.userLevel"
-                    :selection.sync="member.userLevel"
-                    :search="true"
-                  />
-                </div>
-              </td>
-            </tr>
-          </div>
+          <tr v-for="member in projectMembers" :key="member.username">
+            <td>
+              {{ member.user.last_name }} {{ member.user.first_name }}<br /><i
+                >{{ member.user.username }}</i
+              >
+            </td>
+            <td>
+              <div class="required field">
+                <Dropdown
+                  :options="levelOptions"
+                  :selected="member.userLevel.name"
+                  :selection.sync="member.userLevel"
+                  :search="true"
+                />
+              </div>
+            </td>
+          </tr>
         </tbody>
       </table>
 
@@ -59,7 +56,6 @@ import frag from "vue-frag";
 import { mapGetters } from "vuex";
 import Dropdown from "@/components/Dropdown.vue";
 
-
 export default {
   name: "Project_members",
 
@@ -70,52 +66,65 @@ export default {
     Dropdown,
   },
 
-  computed: {
-    ...mapGetters(["project"]),
-  },
-
   data() {
     return {
       projectMembers: [],
       levelOptions: [
-        "Utilisateur connecté",
-        "Contributeur",
-        "Modérateur",
-        "Administrateur projet",
+        { name: "Utilisateur connecté", value: "logged_user" },
+        { name: "Contributeur", value: "contributor" },
+        { name: "Modérateur", value: "moderator" },
+        { name: "Administrateur projet", value: "admin" },
       ],
     };
   },
+
+  computed: {
+    ...mapGetters(["project"]),
+  },
+
   methods: {
     validateMembers() {
-      // const data = {
-      //   slug: this.project.slug,
-      //   data: this.projectMembers,
-      // };
-      // console.log("validateMembers", data);
-      /* axios
-        .post(`${DJANGO_API_BASE}projet/${payload.slug}/utilisateurs/`, payload.data)
+      const data = this.projectMembers.map((member) => {
+        return {
+          user: member.user,
+          level: {
+            display: member.userLevel.name,
+            codename: member.userLevel.value,
+          },
+        };
+      });
+
+      axios
+        .put(
+          `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.project.slug}/utilisateurs/`,
+          data
+        )
         .then((response) => {
-          const user = response.data.user;
+          if (response.status === 200) {
+            this.$store.dispatch("GET_USER_LEVEL_PROJECTS"); //* update user status in top right menu
+          }
         })
-        .catch(() => {
-          router.push({ name: "login" });
-        }); */
+        .catch((error) => {
+          throw error;
+        });
     },
+
     async fetchMembers() {
       return axios
         .get(
           `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.$route.params.slug}/utilisateurs`
         )
-        .then((response) => response.data.members)
+        .then((response) => response.data)
         .catch((error) => {
           throw error;
         });
     },
+
     async populateMembers() {
       await this.fetchMembers().then((members) => {
         this.projectMembers = members.map((el) => {
           return {
-            userLevel: el.userLevel ? el.userLevel : this.levelOptions[0],
+            userLevel: { name: el.level.display, value: el.level.codename },
             ...el,
           };
         });