diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000000000000000000000000000000000000..19fde7ce857b610ee9f16942a080f66878414bf7
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,11 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
+
+## [X.X.X] - 2024-03-04
+
+### Corrections
+
+- Redmine 20344 : Ajout de la documention dans le fichier de config => VUE_APP_URL_DOCUMENTATION
diff --git a/package.json b/package.json
index fbb7a77ad81f5c2ec9896ded94f4a01d62476b4d..018deac37a5f06952db51ec55748ae8fcbb1dc86 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "geocontrib-frontend",
-  "version": "5.4.0",
+  "version": "6.0.0",
   "private": true,
   "scripts": {
     "serve": "npm run init-proxy & npm run init-serve",
diff --git a/public/config/config.json.sample b/public/config/config.json.sample
index a02925f84901b04e3c4f3e37aad826be41da68bc..c48c56f800763b299c5ff60513eca3feb385a3f1 100644
--- a/public/config/config.json.sample
+++ b/public/config/config.json.sample
@@ -37,6 +37,7 @@
         "PROVIDER": "addok"
     },
     "DISPLAY_FORBIDDEN_PROJECTS": true,
-    "DISPLAY_FORBIDDEN_PROJECTS_DEFAULT": true
+    "DISPLAY_FORBIDDEN_PROJECTS_DEFAULT": true,
+    "VUE_APP_URL_DOCUMENTATION": "https://www.onegeosuite.fr/docs/module-geocontrib/intro"
     
 }
\ No newline at end of file
diff --git a/src/components/AppHeader.vue b/src/components/AppHeader.vue
index 89e496d8bff7bd8659f18308e2ff462c568c1919..cbca05f0e62d0e6756e4aa84ba2e18fa4f95de3c 100644
--- a/src/components/AppHeader.vue
+++ b/src/components/AppHeader.vue
@@ -442,7 +442,7 @@ export default {
 
 /* keep above map controls or buttons */
 #app-header {
-  z-index: 1001;
+  z-index: 9999;
   .menu.container .ui.inverted.icon.menu { /* avoid adding space when messages are displayed */
     margin: 0;
     display: flex;
diff --git a/src/components/Dropdown.vue b/src/components/Dropdown.vue
index b4dd8165090efbbe429774d3c11d4f65b46c087f..da33123b153180a105b65a7362b651055ccfe0c8 100644
--- a/src/components/Dropdown.vue
+++ b/src/components/Dropdown.vue
@@ -29,7 +29,7 @@
         <span class="italic">{{ selected[1] }}</span>
       </div>
       <div v-else>
-        {{ selected }}
+        {{ selectedDisplay }}
       </div>
     </div>
     <i
@@ -44,7 +44,7 @@
         :key="option + index"
         :class="[
           filteredOptions ? 'item' : 'message',
-          { 'active selected': option.name === selected },
+          { 'active selected': option.name === selected || option.id === selected },
         ]"
         @click="select(index)"
       >
@@ -114,6 +114,14 @@ export default {
     placehold() {
       return this.input ? '' : this.placeholder;
     },
+
+    selectedDisplay() { // for project attributes, option are object and selected is an id
+      if (this.options[0] && this.options[0].name) {
+        const option = this.options.find(opt => opt.id === this.selected);
+        if (option) return option.name;
+      }
+      return this.selected;
+    }
   },
 
   created() {
diff --git a/src/components/ExtraForm.vue b/src/components/ExtraForm.vue
index d9b56518a31feaf4ce291809df6f27865614bf42..a10641b954ce621e7b8b59014c2400bcb539f2c1 100644
--- a/src/components/ExtraForm.vue
+++ b/src/components/ExtraForm.vue
@@ -96,19 +96,19 @@
         class="checkbox_list"
       >
         <div
-          v-for="(option, index) in field.options"
-          :key="index"
+          v-for="option in field.options"
+          :key="option.id || option"
           class="ui checkbox"
         >
           <input
-            :id="option"
+            :id="option.id || option"
             type="checkbox"
-            :checked="field.value && field.value.includes(option)"
-            :name="option"
+            :checked="field.value && field.value.includes(option.id || option)"
+            :name="option.id || option"
             @change="selectMultipleCheckbox"
           >
-          <label :for="option">
-            {{ option }}
+          <label :for="option.id || option">
+            {{ option.name || option }}
           </label>
         </div>
       </div>
@@ -207,7 +207,7 @@ export default {
       set(newValue) {
         //* set the value selected in the dropdown
         if (this.useValueOnly) {
-          this.$emit('update:value', newValue);
+          this.$emit('update:value', newValue.id || newValue);
         } else {
           const newExtraForm = this.field;
           newExtraForm['value'] = newValue;
diff --git a/src/components/Feature/Detail/FeatureHeader.vue b/src/components/Feature/Detail/FeatureHeader.vue
index b9bcba1d94b4bb26166787c66ec776d6a58e60ed..182073d070809a45a0cf1bc85795b96c9e34f64c 100644
--- a/src/components/Feature/Detail/FeatureHeader.vue
+++ b/src/components/Feature/Detail/FeatureHeader.vue
@@ -98,9 +98,9 @@
                   aria-hidden="true"
                 />
               </button>
-
               <router-link
-                v-if="permissions && permissions.can_create_feature"
+                v-if="permissions && permissions.can_create_feature 
+                  && (featureType && !featureType.geom_type.includes('multi'))"
                 id="add-feature"
                 :to="{
                   name: 'ajouter-signalement',
@@ -303,6 +303,7 @@ export default {
     }
   }
 };
+
 </script>
 
 <style lang="less">
diff --git a/src/components/Map/Geocoder.vue b/src/components/Map/Geocoder.vue
index 0f1a467a3f6e418e835320894d926e7c608572cd..a419e3e36058574b0e7ba93b5d7f7b6e4676a095 100644
--- a/src/components/Map/Geocoder.vue
+++ b/src/components/Map/Geocoder.vue
@@ -1,74 +1,81 @@
 <template>
-  <div
-    id="geocoder-container"
-    :class="{ isExpanded }"
-  >
-    <button
-      class="button-geocoder"
-      title="Rechercher une adresse"
-      type="button"
-      @click="toggleGeocoder"
+  <div>
+    <div
+      id="geocoder-container"
+      :class="{ isExpanded }"
     >
-      <i class="search icon" />
-    </button>
-    <!-- internal-search should be disabled to avoid filtering options, which is done by the api calls anyway https://stackoverflow.com/questions/57813170/vue-multi-select-not-showing-all-the-options -->
-    <!-- otherwise approximate results are not shown (cannot explain why though) -->
-    <Multiselect
-      v-if="isExpanded"
-      ref="multiselect"
-      v-model="selection"
-      class="expanded-geocoder"
-      :options="addresses"
-      :options-limit="limit"
-      :allow-empty="true"
-      :internal-search="false"
-      track-by="id"
-      label="label"
-      :show-labels="false"
-      :reset-after="true"
-      select-label=""
-      selected-label=""
-      deselect-label=""
-      :searchable="true"
-      :placeholder="placeholder"
-      :show-no-results="true"
-      :loading="loading"
-      :clear-on-select="false"
-      :preserve-search="true"
-      @search-change="search"
-      @select="select"
-      @open="retrievePreviousPlaces"
-      @close="close"
+      <button
+        class="button-geocoder"
+        title="Rechercher une adresse"
+        type="button"
+        @click="toggleGeocoder"
+      >
+        <i class="search icon" />
+      </button>
+    </div>
+    <div
+      id="geocoder-select-container"
+      :class="{ isExpanded }"
     >
-      <template
-        slot="option"
-        slot-scope="props"
+      <!-- internal-search should be disabled to avoid filtering options, which is done by the api calls anyway https://stackoverflow.com/questions/57813170/vue-multi-select-not-showing-all-the-options -->
+      <!-- otherwise approximate results are not shown (cannot explain why though) -->
+      <Multiselect
+        v-if="isExpanded"
+        ref="multiselect"
+        v-model="selection"
+        class="expanded-geocoder"
+        :options="addresses"
+        :options-limit="limit"
+        :allow-empty="true"
+        :internal-search="false"
+        track-by="id"
+        label="label"
+        :show-labels="false"
+        :reset-after="true"
+        select-label=""
+        selected-label=""
+        deselect-label=""
+        :searchable="true"
+        :placeholder="placeholder"
+        :show-no-results="true"
+        :loading="loading"
+        :clear-on-select="false"
+        :preserve-search="true"
+        @search-change="search"
+        @select="select"
+        @open="retrievePreviousPlaces"
+        @close="close"
       >
-        <div class="option__desc">
-          <span class="option__title">{{ props.option.label }}</span>
-        </div>
-      </template>
-      <template slot="clear">
-        <div
-          v-if="selection"
-          class="multiselect__clear"
-          @click.prevent.stop="selection = null"
+        <template
+          slot="option"
+          slot-scope="props"
         >
-          <i class="close icon" />
-        </div>
-      </template>
-      <span slot="noResult">
-        Aucun résultat.
-      </span>
-      <span slot="noOptions">
-        Saisissez les premiers caractères ...
-      </span>
-    </Multiselect>
-    <div style="display: none;">
-      <div
-        id="marker"
-        title="Marker"
-      />
+          <div class="option__desc">
+            <span class="option__title">{{ props.option.label }}</span>
+          </div>
+        </template>
+        <template slot="clear">
+          <div
+            v-if="selection"
+            class="multiselect__clear"
+            @click.prevent.stop="selection = null"
+          >
+            <i class="close icon" />
+          </div>
+        </template>
+        <span slot="noResult">
+          Aucun résultat.
+        </span>
+        <span slot="noOptions">
+          Saisissez les premiers caractères ...
+        </span>
+      </Multiselect>
+      <div style="display: none;">
+        <div
+          id="marker"
+          title="Marker"
+        />
+      </div>
     </div>
   </div>
 </template>
@@ -150,6 +157,7 @@ export default {
         mapService.addOverlay(this.selectedAddress.geometry.coordinates, zoomlevel);
         // On enregistre l'adresse sélectionné pour le proposer à la prochaine recherche
         this.setLocalstorageSelectedAdress(this.selectedAddress);
+        this.toggleGeocoder();
       }
     },
 
@@ -250,11 +258,26 @@ export default {
 
   &&.isExpanded {
     .button-geocoder {
-      height: 41px;
+      /*height: 41px;*/
       color: rgb(99, 99, 99);
       border-radius: 2px 0 0 2px;
     }
   }
+}
+
+#geocoder-select-container{
+  position: absolute;
+  right: 46px;
+  // each button have (more or less depends on borders) .5em space between
+  // zoom buttons are 60px high, geolocation and full screen button is 34px high with borders
+  top: calc(1.6em + 60px + 34px + 34px - 4px);
+  pointer-events: auto;
+  z-index: 999;
+  border: 2px solid rgba(0,0,0,.2);
+  background-clip: padding-box;
+  padding: 0;
+  border-radius: 4px;
+  display: flex;
   // /* keep placeholder width when opening dropdown */
   .multiselect {
     min-width: 208px;
@@ -280,6 +303,7 @@ export default {
   .multiselect__tags {
     border: 0 !important;
     min-height: 41px !important;
+    padding: 10px 40px 0 8px;
   }
   .multiselect input {
     line-height: 1em !important;
@@ -288,6 +312,7 @@ export default {
   .multiselect__content-wrapper {
     border: 2px solid rgba(0,0,0,.2);
   }
+
 }
 </style>
       
\ No newline at end of file
diff --git a/src/components/Project/Detail/ProjectFeatureTypes.vue b/src/components/Project/Detail/ProjectFeatureTypes.vue
index a9163fbdce2460669f2e6ed02752d2b47fe6c647..faad82a3a85b4dcb3e8e4bab4858dd4b3dd94fcf 100644
--- a/src/components/Project/Detail/ProjectFeatureTypes.vue
+++ b/src/components/Project/Detail/ProjectFeatureTypes.vue
@@ -429,7 +429,8 @@ export default {
     },
 
     goToDocumentation() {
-      window.open('https://geocontrib.readthedocs.io/fr/latest/documentation_fonctionnelle/import_export/');
+      
+      window.open(this.configuration.VUE_APP_URL_DOCUMENTATION);
     },
 
     toNewGeojsonFeatureType() {
diff --git a/src/components/Project/Edition/ProjectAttributeForm.vue b/src/components/Project/Edition/ProjectAttributeForm.vue
index 6b2f3d5a1a600573509d344c31e20ef00aa3d8c5..f00d352733ffe1c78c4f298f6e4c399db6298698 100644
--- a/src/components/Project/Edition/ProjectAttributeForm.vue
+++ b/src/components/Project/Edition/ProjectAttributeForm.vue
@@ -60,8 +60,8 @@ export default {
   },
 
   created() {
-    // Checks if the component is being used in the context of creating a new project.
-    if (this.$route.name === 'project_create') {
+    // Checks if the component is being used in the context of creating a new project and attribute's default value is set
+    if (this.$route.name === 'project_create' && this.attribute.default_value !== null) {
       // If so, initializes the attribute's value with its default value as defined in the attribute's settings.
       this.updateValue(this.attribute.default_value, this.attribute.id);
     }
diff --git a/src/components/Project/FeaturesListAndMap/FeaturesListAndMapFilters.vue b/src/components/Project/FeaturesListAndMap/FeaturesListAndMapFilters.vue
index 926d8201efb8ce836efe928ffe614ad9de2f44ce..981962f573a941e630eb71149852b6ecf2cb73bb 100644
--- a/src/components/Project/FeaturesListAndMap/FeaturesListAndMapFilters.vue
+++ b/src/components/Project/FeaturesListAndMap/FeaturesListAndMapFilters.vue
@@ -403,7 +403,7 @@ export default {
     width: 100%;
     margin-left: 25%;
     .secondary.menu  #button-dropdown {
-      z-index: 1;
+      z-index: 10;
       margin-right: 0;
       padding-right: 0;
     }
diff --git a/src/components/Projects/DropdownMenuItem.vue b/src/components/Projects/DropdownMenuItem.vue
index 8c16b6312e8767cce9cbff2a6f46d13111cc18d7..6282644c46d17600a2f8755b7d95296b4ed58166 100644
--- a/src/components/Projects/DropdownMenuItem.vue
+++ b/src/components/Projects/DropdownMenuItem.vue
@@ -39,7 +39,7 @@
       <span
         v-else
         class="multiselect__single"
-      >{{ currentSelection || selection.label }}</span>
+      >{{ currentSelectionLabel || selection.label }}</span>
     </template>
   </Multiselect>
 </template>
@@ -85,6 +85,16 @@ export default {
     };
   },
 
+  computed: {
+    /**
+     * Get the label of an option to work with project attributes options as JSON
+     */
+    currentSelectionLabel() {
+      const option = this.options.find(opt => opt.value === this.currentSelection);
+      return option ? option.label : '';
+    }
+  },
+
   watch: {
     selection: {
       deep: true,
diff --git a/src/components/Projects/ProjectsMenu.vue b/src/components/Projects/ProjectsMenu.vue
index d37b8068464ba1a8afd2b11ea86b8301a0c0023a..0fbeb7877f1f0c47727e6f6ce6f89263a7f6c127 100644
--- a/src/components/Projects/ProjectsMenu.vue
+++ b/src/components/Projects/ProjectsMenu.vue
@@ -1,8 +1,7 @@
 <template>
   <div
-    v-if="chunkedNsortedFilters"
+    v-if="chunkedNsortedFilters.length > 0"
     id="filters-container"
-    class="margin-bottom"
   >
     <div
       class="ui styled accordion"
@@ -191,8 +190,9 @@ export default {
      * @returns {Array} An array of arrays, where each sub-array contains up to 4 project attributes with modified options for display.
      */
     displayedAttributeFilters() {
-      // Filter and process attributes
-      return this.projectAttributes.filter(attribute => attribute.display_filter)
+      // Filter displayed filters & filter only attribute of boolean type (no need for option property) or list type with options
+      return this.projectAttributes.filter(attribute => attribute.display_filter && (attribute.field_type === 'boolean' || attribute.options))
+        // Process attributes for display
         .map(attribute => {
           // Format the options to be displayed by dropdowns
           const options = this.generateFilterOptions(attribute);
@@ -251,14 +251,15 @@ export default {
           { filter: filter.id, label: 'Oui', value: 'true' },
           { filter: filter.id, label: 'Non', value: 'false' },
         ];
+      } else if (filter.options) {
+        // For other filter types, map each option to the expected format
+        return filter.options.map(option => ({
+          filter: filter.id || filter.name,
+          label: option.name || option.label || option,
+          value: option.id || option.value || option,
+        }));
       }
-      
-      // For other filter types, map each option to the expected format
-      return filter.options.map(option => ({
-        filter: filter.id || filter.name,
-        label: option.label || option,
-        value: option.value || option,
-      }));
+      return [];
     },
     
     /**
@@ -388,6 +389,7 @@ export default {
 		height:auto;
 		max-height:100vh;
     opacity: 1;
+    z-index: 1001;
 		.transition-properties(all 0.2s ease;);
     .filter-row {
       border: none;
diff --git a/src/router/index.js b/src/router/index.js
index ee401ccc3c00016818c0060fb383c7535a64a21d..ab3b4f44f18f53a5c3eb0de64ab278fe256229e2 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -130,11 +130,16 @@ const routes = [
           query['feature_type_slug'] = slug_type_signal; // set feature_type slug in query
         }
         const offset = await featureAPI.getFeaturePosition(slug, slug_signal, query);
-        next({ 
-          name: 'details-signalement-filtre', 
-          params: { slug }, 
-          query: { ...query, offset } 
-        });        
+        if (offset) {
+          next({ 
+            name: 'details-signalement-filtre', 
+            params: { slug }, 
+            query: { ...query, offset } 
+          });        
+        } else {
+          store.commit('DISPLAY_MESSAGE', { comment: 'Désolé, une erreur est survenue pendant la recherche du signalement', level: 'negative' });
+          next({ path: '/' });
+        }
       } catch (error) {
         console.error('error', error);
         store.commit('DISPLAY_MESSAGE', { comment: `Désolé, une erreur est survenue pendant la recherche du signalement   -   ${error}`, level: 'negative' });
diff --git a/src/services/map-service.js b/src/services/map-service.js
index fd61e476439f587bed287b4b2c7c44828e238444..f12c94b4a59f42c1bdc06ada50319b7591ab0876 100644
--- a/src/services/map-service.js
+++ b/src/services/map-service.js
@@ -230,7 +230,7 @@ const mapService = {
         this.overlay.setPosition(event.coordinate);
         this.addRouterToPopup({
           featureId,
-          featureTypeSlug: popupContent.featureType ? popupContent.featureType.slug : '',
+          featureTypeSlug: popupContent.feature_type ? popupContent.feature_type.slug : '',
           index: popupContent.index,
         });
       }
@@ -383,7 +383,7 @@ const mapService = {
   },
 
   addWMSLayer: function (url, options) {
-    options.VERSION = '1.1.1'; // pour compatibilité avec le proxy django
+    options.VERSION = options.version || '1.3.0'; // pour compatibilité avec le proxy django
     const source = new TileWMS({
       attributions: options.attribution,
       url: url,
diff --git a/src/store/index.js b/src/store/index.js
index 0ec3156209fb8b15e59769e24a0bb07ff23c2f39..0578ae4056a55aab189f1a51ad2b23fd1d37e1cf 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -183,33 +183,62 @@ export default new Vuex.Store({
         });
       }
     },
-
+    /**
+     * Action to retrieve user information.
+     * - If a token is present in the URL, it indicates a Single Sign-On (SSO) attempt, 
+     * in which case it logs out the user (if logged in) and connects via SSO with the token.
+     * Otherwise, it fetches user information from the Django API endpoint:
+     * - If no user is logged AND if the login should be done through SSO with a redirect,
+     * it naviguates to the login plateform, afterwards the user will be redirected with the token and the original url to open in geocontrib
+     * - Else it displays a message that the user is not logged but can still access the app as an anonymous user.
+     */
     async GET_USER_INFO({ state, commit, dispatch }) {
-      const token = new URLSearchParams(window.location.search).get('token');
-      if (token && this.state.configuration.VUE_APP_LOGIN_URL) {
-        // if user was previously connected through SSO, make sure he's logout before connecting through SSO, in case user changed
+      // Extract token from URL query parameters
+      const searchParams = new URLSearchParams(window.location.search);
+      const token = searchParams.get('token');
+      const url_redirect = searchParams.get('url_redirect');
+      // Check if token exists and SSO login URL is configured
+      if (token && state.configuration.VUE_APP_LOGIN_URL) {
+        // If user was previously connected through SSO, ensure they are logged out before reconnecting through SSO, in case user changed
         await dispatch('LOGOUT');
-        dispatch('CONNECT_SSO_WITH_TOKEN', token);
+        dispatch('CONNECT_SSO_WITH_TOKEN', { token, url_redirect });
       } else if (!state.user) {
+        // If user infos are not set, try to fetch them
         axios
-          .get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}user_info/`)
+          .get(`${state.configuration.VUE_APP_DJANGO_API_BASE}user_info/`)
           .then((response) => {
+            // Update the user state with received user data
             if (response && response.status === 200) {
               const user = response.data.user;
               commit('SET_USER', user);
             }
           })
-          .catch((err) => {
-            console.error(err);
-            commit('DISPLAY_MESSAGE', {
-              comment: `Vous n'êtes pas connecté actuellement.
-                Vous pouvez accéder à l'application en tant qu'utilisateur anonyme`
-            });
+          .catch(() => {
+            // If the instance is set to accept login with redirection
+            if (state.configuration.VUE_APP_SSO_LOGIN_URL_WITH_REDIRECT) {
+              commit('DISPLAY_MESSAGE', {
+                comment: 'Vous allez être redirigé vers la plateforme de connexion.'
+              });
+              // Call the SSO login plateform with url to redirect after login
+              window.open(`${state.configuration.VUE_APP_SSO_LOGIN_URL_WITH_REDIRECT}/?url_redirect=${window.location.href}`, '_self');
+            } else {
+              // If the user is not logged in, display an info message
+              commit('DISPLAY_MESSAGE', {
+                comment: `Vous n'êtes pas connecté actuellement.
+                  Vous pouvez accéder à l'application en tant qu'utilisateur anonyme`
+              });
+            }
           });
       }
     },
-
-    async CONNECT_SSO_WITH_TOKEN({ state, commit, dispatch }, token) {
+    /**
+     * Action to connect user through SSO with a token.
+     * If the app was opened with a token in the url, it attempts a login,
+     * if the login is succesfull, it set the user in the state
+     * and retrieve information that would have been retrieved in GET_USER_INFO when logged.
+     * If the url contained a url to redirect, it calls the router to open this page.
+     */
+    async CONNECT_SSO_WITH_TOKEN({ state, commit, dispatch }, { token, url_redirect }) {
       axios
         .get(`${state.configuration.VUE_APP_DJANGO_API_BASE}login-token/?token=${token}`)
         .then((response) => {
@@ -219,15 +248,29 @@ export default new Vuex.Store({
             dispatch('GET_USER_LEVEL_PROJECTS');
             dispatch('GET_USER_LEVEL_PERMISSIONS');
             commit('DISPLAY_MESSAGE', {
-              comment: `Vous êtes maintenant connecté ${ user.first_name} ${ user.last_name}`, level: 'positive'
+              comment: `Vous êtes maintenant connecté ${user.first_name} ${user.last_name}`,
+              level: 'positive'
             });
             dispatch('projects/GET_PROJECTS');
+            if (url_redirect) {
+              // Prepare the url to redirect with vue-router that prefix the url with DOMAIN+BASE_URL
+              const substringToRemove = state.configuration.BASE_URL;
+              // Find the index of the string to remove
+              const index = url_redirect.indexOf(substringToRemove);
+              // If found, keep only the remaining part after the substring to remove
+              if (index !== -1) {
+                url_redirect = index !== -1 ? url_redirect.substring(index + substringToRemove.length) : url_redirect;
+              }
+              // catch error from the router, because of second redirection to feature when call with a feature's id
+              router.push(url_redirect).catch((e) => e);
+            }
           }
         })
         .catch((err) => {
           console.error(err);
           commit('DISPLAY_MESSAGE', {
-            comment: 'La connexion a échoué.', level: 'negative'
+            comment: 'La connexion a échoué.',
+            level: 'negative'
           });
         });
     },
diff --git a/src/views/Project/ProjectEdit.vue b/src/views/Project/ProjectEdit.vue
index d3f6890357aab470cb4a362f735f197d7a271359..e9ce66bb553843c7afc822ac0028beee3cc79721 100644
--- a/src/views/Project/ProjectEdit.vue
+++ b/src/views/Project/ProjectEdit.vue
@@ -300,13 +300,16 @@
       </div>
 
 
-      <div class="ui horizontal divider">
+      <div
+        v-if="filteredAttributes.length > 0"
+        class="ui horizontal divider"
+      >
         ATTRIBUTS
       </div>
       
       <div class="fields grouped">
         <ProjectAttributeForm
-          v-for="(attribute, index) in projectAttributes"
+          v-for="(attribute, index) in filteredAttributes"
           :key="index"
           :attribute="attribute"
           :form-project-attributes="form.project_attributes"
@@ -357,7 +360,6 @@ export default {
         name: 'Sélectionner une image ...',
         size: 0,
       },
-      errors_archive_feature: [],
       errors: {
         title: [],
         access_level_pub_feature: [],
@@ -394,8 +396,6 @@ export default {
         creator: null,
         access_level_pub_feature: { name: '', value: '' },
         access_level_arch_feature: { name: '', value: '' },
-        archive_feature: 0,
-        delete_feature: 0,
         map_max_zoom_level: 22,
         nb_features: 0,
         nb_published_features: 0,
@@ -482,7 +482,14 @@ export default {
         });
       }
       return levels;
-    }
+    },
+    /**
+     * Filter out attribute of field type list without option
+     */
+    filteredAttributes() {
+      return this.projectAttributes.filter(attr => attr.field_type === 'boolean' || attr.options);
+    },
+
   },
 
   watch: {
@@ -594,16 +601,6 @@ export default {
       }
     },
 
-    checkEmpty() {
-      //* forbid empty fields
-      if (!this.form.archive_feature) {
-        this.form.archive_feature = 0;
-      }
-      if (!this.form.delete_feature) {
-        this.form.delete_feature = 0;
-      }
-    },
-
     goBackNrefresh(slug) {
       Promise.all([
         this.$store.dispatch('GET_USER_LEVEL_PROJECTS'), //* refresh projects user levels
@@ -652,12 +649,6 @@ export default {
     },
 
     checkForm() {
-      if (this.form.archive_feature > this.form.delete_feature) {
-        this.errors_archive_feature.push(
-          "Le délais de suppression doit être supérieur au délais d'archivage."
-        );
-        return false;
-      }
       for (const key in this.errors) {
         if ((key === 'title' && this.form[key]) || this.form[key].value) {
           this.errors[key] = [];
diff --git a/src/views/Projects/ProjectsList.vue b/src/views/Projects/ProjectsList.vue
index 9682c5814278b5510053cdce53a4b3f51560ea51..02eccb1ce8fd30be9ebe9bdaf305f615b7ed78c8 100644
--- a/src/views/Projects/ProjectsList.vue
+++ b/src/views/Projects/ProjectsList.vue
@@ -42,7 +42,7 @@
     <div
       v-if="configuration.DISPLAY_FORBIDDEN_PROJECTS"
       id="forbidden-projects"
-      class="ui toggle checkbox"
+      class="ui toggle checkbox margin-top"
     >
       <input
         :checked="displayForbiddenProjects"
@@ -60,10 +60,7 @@
       class="ui divided items dimmable dimmed"
       data-test="project-list"
     >
-      <div
-        :class="{ active: loading }"
-        class="ui inverted dimmer"
-      >
+      <div :class="['ui inverted dimmer', { active: loading }]">
         <div class="ui loader" />
       </div>