diff --git a/src/components/Project/FeaturesListAndMap/FeaturesListAndMapFilters.vue b/src/components/Project/FeaturesListAndMap/FeaturesListAndMapFilters.vue
index ecefd999458cfbcd174bd6ae9402a7bc5d5b508b..2fc77496d4686f9c59aeb8022792c8c369a43abb 100644
--- a/src/components/Project/FeaturesListAndMap/FeaturesListAndMapFilters.vue
+++ b/src/components/Project/FeaturesListAndMap/FeaturesListAndMapFilters.vue
@@ -142,12 +142,16 @@
         :class="['field column', { 'disabled': !isOnline }]"
       >
         <label>Type</label>
-        <Dropdown
-          :options="featureTypeTitles"
-          :selected="form.type.selected"
-          :selection.sync="form.type.selected"
-          :search="true"
-          :clearable="true"
+        <Multiselect
+          v-model="form.type"
+          :options="featureTypeOptions"
+          :multiple="true"
+          :searchable="false"
+          :close-on-select="false"
+          :show-labels="false"
+          placeholder="Sélectionner un type"
+          track-by="value"
+          label="name"
         />
       </div>
       <div
@@ -155,13 +159,16 @@
         :class="['field column', { 'disabled': !isOnline }]"
       >
         <label>Statut</label>
-        <!--  //* giving an object mapped on key name -->
-        <Dropdown
-          :options="filteredStatusChoices"
-          :selected="form.status.selected.name"
-          :selection.sync="form.status.selected"
-          :search="true"
-          :clearable="true"
+        <Multiselect
+          v-model="form.status"
+          :options="statusOptions"
+          :multiple="true"
+          :searchable="false"
+          :close-on-select="false"
+          :show-labels="false"
+          placeholder="Sélectionner un statut"
+          track-by="value"
+          label="name"
         />
       </div>
       <div
@@ -200,11 +207,10 @@
 
 <script>
 import { mapState, mapGetters } from 'vuex';
+import Multiselect from 'vue-multiselect';
 
 import { statusChoices, allowedStatus2change } from '@/utils';
 
-import Dropdown from '@/components/Dropdown.vue';
-
 const initialPagination = {
   currentPage: 1,
   pagesize: 15,
@@ -217,7 +223,7 @@ export default {
   name: 'FeaturesListAndMapFilters',
 
   components: {
-    Dropdown
+    Multiselect
   },
 
   props: {
@@ -247,12 +253,8 @@ export default {
   data() {
     return {
       form: {
-        type: {
-          selected: '',
-        },
-        status: {
-          selected: '',
-        },
+        type: [],
+        status: [],
         title: null,
       },
       lat: null,
@@ -295,7 +297,10 @@ export default {
     featureTypeTitles() {
       return this.feature_types.map((el) => el.title);
     },
-    filteredStatusChoices() {
+    featureTypeOptions() {
+      return this.feature_types.map((el) => ({ name: el.title, value: el.slug }));
+    },
+    statusOptions() {
       //* if project is not moderate, remove pending status
       return statusChoices.filter((el) =>
         this.project && this.project.moderation ? true : el.value !== 'pending'
@@ -309,11 +314,11 @@ export default {
   },
 
   watch: {
-    'form.type.selected'(newValue) {
+    'form.type'(newValue) {
       this.$emit('set-filter', { type: newValue });
       this.resetPaginationNfetchFeatures();
     },
-    'form.status.selected': {
+    'form.status': {
       deep: true,
       handler(newValue) {
         this.$emit('set-filter', { status: newValue });
@@ -407,6 +412,9 @@ export default {
 
 #form-filters {
   margin: 0;
+  label + div {
+    min-height: 42px;
+  }
 }
 
 .ui.dropdown .menu .left.menu, .ui.dropdown > .left.menu .menu {
@@ -456,3 +464,9 @@ export default {
   }
 }
 </style>
+
+<style>
+#form-filters .multiselect__tags {
+  white-space: normal !important;
+}
+</style>
\ No newline at end of file
diff --git a/src/services/feature-api.js b/src/services/feature-api.js
index 04e9400fb61c06eed4e2c6bb6e704c8d8b9a5b40..aa2ba11505e7b567aa9feae4b84ee3deab83d630 100644
--- a/src/services/feature-api.js
+++ b/src/services/feature-api.js
@@ -3,10 +3,10 @@ import store from '../store';
 
 
 const featureAPI = {
-  async getFeaturesBbox(project_slug, queryParams) {
+  async getFeaturesBbox(project_slug, queryString) {
     const baseUrl = store.state.configuration.VUE_APP_DJANGO_API_BASE;
     const response = await axios.get(
-      `${baseUrl}projects/${project_slug}/feature-bbox/${queryParams ? '?' + queryParams : ''}`
+      `${baseUrl}projects/${project_slug}/feature-bbox/${queryString ? '?' + queryString : ''}`
     );
     if (
       response.status === 200 &&
diff --git a/src/services/map-service.js b/src/services/map-service.js
index a864d2cbdad7e2fb1e7f0b73e79324f03649c40c..fd61e476439f587bed287b4b2c7c44828e238444 100644
--- a/src/services/map-service.js
+++ b/src/services/map-service.js
@@ -596,81 +596,76 @@ const mapService = {
     window.layerMVT = this.mvtLayer;
   },
 
+  /**
+   * Determines the style for a given feature based on its type and applicable filters.
+   * 
+   * @param {Object} feature - The feature to style.
+   * @param {Array} featureTypes - An array of available feature types.
+   * @param {Object} formFilters - Filters applied through the form.
+   * @returns {ol.style.Style} - The OpenLayers style for the feature.
+   */
   getStyle: function (feature, featureTypes, formFilters) {
     const properties = feature.getProperties();
     let featureType;
-    // GeoJSON
+
+    // Determine the feature type. Differentiate between GeoJSON and MVT sources.
     if (properties && properties.feature_type) {
+      // Handle GeoJSON feature type
       featureType = featureTypes
         .find((ft) => ft.slug === (properties.feature_type.slug || properties.feature_type));
-    } else { //MVT
+    } else {
+      // Handle MVT feature type
       featureType = featureTypes.find((x) => x.slug.split('-')[0] === '' + properties.feature_type_id);
     }
 
     if (featureType) {
+      // Retrieve the style (color, opacity) for the feature.
       const { color, opacity } = this.retrieveFeatureStyle(featureType, properties);
-      const colorValue =
-        color && color.value && color.value.length ?
-          color.value : typeof color === 'string' && color.length ?
-            color : '#000000';
+      let colorValue = '#000000'; // Default color
+
+      // Determine the color value based on the feature type.
+      if (color && color.value && color.value.length) {
+        colorValue = color.value;
+      } else if (typeof color === 'string' && color.length) {
+        colorValue = color;
+      }
 
+      // Convert the color value to RGBA and apply the opacity.
       const rgbaColor = asArray(colorValue);
-      rgbaColor[3] = opacity || 0.5;//opacity
-
-      const defaultStyle = new Style(
-        {
-          image: new Circle({
-            fill: new Fill(
-              {
-                color: rgbaColor,
-              },
-            ),
-            stroke: new Stroke(
-              {
-                color: colorValue,
-                width: 2,
-              },
-            ),
-            radius: 5,
-          }),
-          stroke: new Stroke(
-            {
-              color: colorValue,
-              width: 2,
-            },
-          ),
-          fill: new Fill(
-            {
-              color: rgbaColor,
-            },
-          ),
-        },
-      );
-      const hiddenStyle = new Style(); // hide the feature to apply filters
-      // Filtre sur le feature type
+      rgbaColor[3] = opacity || 0.5; // Default opacity
+
+      // Define the default style for the feature.
+      const defaultStyle = new Style({
+        image: new Circle({
+          fill: new Fill({ color: rgbaColor }),
+          stroke: new Stroke({ color: colorValue, width: 2 }),
+          radius: 5,
+        }),
+        stroke: new Stroke({ color: colorValue, width: 2 }),
+        fill: new Fill({ color: rgbaColor }),
+      });
+
+      // Define a hidden style to apply when filters are active.
+      const hiddenStyle = new Style();
+
+      // Apply filters based on feature type, status, and title.
       if (formFilters) {
-        if (formFilters.type && formFilters.type.selected) {
-          if (featureType.title !== formFilters.type.selected) {
-            return hiddenStyle;
-          }
+        if (formFilters.type && formFilters.type.length > 0 && !formFilters.type.includes(featureType.slug)) {
+          return hiddenStyle;
         }
-        // Filtre sur le statut
-        if (formFilters.status && formFilters.status.selected.value) {
-          if (properties.status !== formFilters.status.selected.value) {
-            return hiddenStyle;
-          }
+        if (formFilters.status && formFilters.status.length > 0 && !formFilters.status.includes(properties.status)) {
+          return hiddenStyle;
         }
-        // Filtre sur le titre
-        if (formFilters.title) {
-          if (!properties.title.toLowerCase().includes(formFilters.title.toLowerCase())) {
-            return hiddenStyle;
-          }
+        if (formFilters.title && !properties.title.toLowerCase().includes(formFilters.title.toLowerCase())) {
+          return hiddenStyle;
         }
       }
+
+      // Return the default style if no filters are applied or if the feature passes the filters.
       return defaultStyle;
     } else {
       console.error('No corresponding featureType found.');
-      return;
+      return new Style();
     }
   },
 
diff --git a/src/views/Feature/FeatureDetail.vue b/src/views/Feature/FeatureDetail.vue
index 9068857a9ba1f8542588e13f2ecb36970d7da9da..e026674d96e069f8287afa7a1fe9fbb9699c20c5 100644
--- a/src/views/Feature/FeatureDetail.vue
+++ b/src/views/Feature/FeatureDetail.vue
@@ -508,7 +508,6 @@ export default {
         project_slug: this.slug,
         features: [this.currentFeature],
         featureTypes: this.feature_types,
-
         addToMap: true,
       });
       mapService.fitExtent(buffer(featureGroup.getExtent(),200));
diff --git a/src/views/Project/FeaturesListAndMap.vue b/src/views/Project/FeaturesListAndMap.vue
index e25a394279fc71c27cf486a1e6eaccbc0c0a350e..8feba95fc9fc2111e5418548fcd6e08b9bef5d72 100644
--- a/src/views/Project/FeaturesListAndMap.vue
+++ b/src/views/Project/FeaturesListAndMap.vue
@@ -136,12 +136,8 @@ export default {
       featuresCount: 0,
       featuresWithGeomCount:0,
       form: {
-        type: {
-          selected: '',
-        },
-        status: {
-          selected: '',
-        },
+        type: [],
+        status: [],
         title: null,
       },
       isDeleteModalOpen: false,
@@ -241,14 +237,19 @@ export default {
     resetPagination() {
       this.pagination = { ...initialPagination };
     },
+    
+    /**
+     * Updates the filters based on the provided key-value pair.
+     *
+     * @param {Object} e - The key-value pair representing the filter to update.
+     */
     setFilters(e) {
       const filter = Object.keys(e)[0];
-      const value = Object.values(e)[0];
-      if (filter === 'title') {
-        this.form[filter] = value;
-      } else {
-        this.form[filter].selected = value;
+      let value = Object.values(e)[0];
+      if (value && Array.isArray(value)) {
+        value = value.map(el => el.value);
       }
+      this.form[filter] = value;
     },
 
     toggleDeleteModal() {
@@ -295,18 +296,19 @@ export default {
       const promises = this.checkedFeatures.map(
         (feature_id) => this.DELETE_FEATURE({ feature_id, noFeatureType: true })
       );
-      Promise.all(promises).then((response) => {
-        const deletedFeaturesCount = response.reduce((acc, curr) => curr.status === 204 ? acc += 1 : acc, 0);
-        const newFeaturesCount = initialFeaturesCount - deletedFeaturesCount;
-        const newPagesArray = this.createPagesArray(newFeaturesCount, this.pagination.pagesize);
-        const newLastPageNum = newPagesArray[newPagesArray.length - 1];
-        this.$store.commit('feature/UPDATE_CHECKED_FEATURES', []);
-        if (initialCurrentPage > newLastPageNum) { //* if page doesn't exist anymore
-          this.toPage(newLastPageNum); //* go to new last page
-        } else {
-          this.fetchPagedFeatures();
-        }
-      })
+      Promise.all(promises)
+        .then((response) => {
+          const deletedFeaturesCount = response.reduce((acc, curr) => curr.status === 204 ? acc += 1 : acc, 0);
+          const newFeaturesCount = initialFeaturesCount - deletedFeaturesCount;
+          const newPagesArray = this.createPagesArray(newFeaturesCount, this.pagination.pagesize);
+          const newLastPageNum = newPagesArray[newPagesArray.length - 1];
+          this.$store.commit('feature/UPDATE_CHECKED_FEATURES', []);
+          if (initialCurrentPage > newLastPageNum) { //* if page doesn't exist anymore
+            this.toPage(newLastPageNum); //* go to new last page
+          } else {
+            this.fetchPagedFeatures();
+          }
+        })
         .catch((err) => console.error(err));
       this.toggleDeleteModal();
     },
@@ -361,9 +363,9 @@ export default {
       this.fetchPagedFeatures();
     },
 
-    fetchBboxNfit(queryParams) {
+    fetchBboxNfit(queryString) {
       featureAPI
-        .getFeaturesBbox(this.projectSlug, queryParams)
+        .getFeaturesBbox(this.projectSlug, queryString)
         .then((bbox) => {
           if (bbox) {
             mapService.fitBounds(bbox);
@@ -387,66 +389,73 @@ export default {
       return result;
     },
 
-    buildQueryString() {
-      let queryString = '';
-      const typeFilter = this.getFeatureTypeSlug(this.form.type.selected);
-      const statusFilter = this.form.status.selected.value;
-
+    /**
+     * Updates the query parameters based on the current state of the pagination and form filters.
+     * This function sets various parameters like offset, feature_type_slug, status__value, title,
+     * and ordering to be used in an API request and to filter hidden features on mvt tiles.
+     */
+    updateQueryParams() {
+      // empty queryparams to remove params when removed from the form
+      this.queryparams = {};
+      // Update the 'offset' parameter based on the current pagination start value.
       this.queryparams['offset'] = this.pagination.start;
-      if (typeFilter) {
-        this.queryparams['feature_type_slug'] = typeFilter;
-        queryString += `&feature_type_slug=${typeFilter}`;
+      // Set 'feature_type_slug' if a type is selected in the form.
+      if (this.form.type.length > 0) {
+        this.queryparams['feature_type_slug'] = this.form.type;
       }
-      if (statusFilter) {
-        this.queryparams['status__value'] = statusFilter;
-        queryString += `&status__value=${statusFilter}`;
+      // Set 'status__value' if a status is selected in the form.
+      if (this.form.status.length > 0) {
+        this.queryparams['status__value'] = this.form.status;
       }
+      // Set 'title' if a title is entered in the form.
       if (this.form.title) {
         this.queryparams['title'] = this.form.title;
-        queryString += `&title=${this.form.title}`;
-      }
-      if (this.sort.column) {
-        let ordering = `${this.sort.ascending ? '-' : ''}${this.getAvalaibleField(this.sort.column)}`;
-        this.queryparams['ordering'] = ordering;
-        queryString += `&ordering=${ordering}`;
       }
-      return queryString;
+      // Update the 'ordering' parameter based on the current sorting state.
+      // Prepends a '-' for descending order if sort.ascending is false.
+      this.queryparams['ordering'] = `${this.sort.ascending ? '-' : ''}${this.getAvalaibleField(this.sort.column)}`;
     },
 
-    fetchPagedFeatures(newUrl) {
+    /**
+     * Fetches paginated feature data from the API.
+     * This function is called to retrieve a specific page of features based on the current pagination settings and any applied filters.
+     * If the application is offline, it displays a message and does not proceed with the API call.
+     */
+    fetchPagedFeatures() {
+      // Check if the application is online; if not, display a message and return.
       if (!this.isOnline) {
         this.DISPLAY_MESSAGE({
           comment: 'Les signalements du projet non mis en cache ne sont pas accessibles en mode déconnecté',
         });
         return;
       }
-      let url = `${this.API_BASE_URL}projects/${this.projectSlug}/feature-paginated/?limit=${this.pagination.pagesize}&offset=${this.pagination.start}`;
-      //* if receiving next & previous url (// todo : might be not used anymore, to check)
-      if (newUrl && typeof newUrl === 'string') {
-        //newUrl = newUrl.replace("8000", "8010"); //* for dev uncomment when using proxy link
-        url = newUrl;
-      }
-      const queryString = this.buildQueryString();
 
-      url += queryString;
-      this.$store.commit(
-        'DISPLAY_LOADER',
-        'Récupération des signalements en cours...'
-      );
+      // Display a loading message.
+      this.$store.commit('DISPLAY_LOADER', 'Récupération des signalements en cours...');
+
+      // Update additional query parameters based on the current filter states.
+      this.updateQueryParams();
+      const queryString = new URLSearchParams(this.queryparams).toString();
+      // Construct the base URL with query parameters.
+      const url = `${this.API_BASE_URL}projects/${this.projectSlug}/feature-paginated/?limit=${this.pagination.pagesize}&${queryString}`;
+      // Make an API call to get the paginated features.
       featureAPI.getPaginatedFeatures(url)
         .then((data) => {
           if (data) {
+            // Update the component state with the data received from the API.
             this.featuresCount = data.count;
             this.featuresWithGeomCount = data.geom_count;
             this.previous = data.previous;
             this.next = data.next;
             this.paginatedFeatures = data.results;
           }
-          //* bbox needs to be updated with the same filters
+          // If there are features, update the bounding box.
           if (this.paginatedFeatures.length) {
             this.fetchBboxNfit(queryString);
           }
-          this.onFilterChange(); //* use paginated event to watch change in filters and modify features on map
+          // Trigger actions on filter change.
+          this.onFilterChange();
+          // Hide the loading message.
           this.$store.commit('DISCARD_LOADER');
         });
     },
@@ -476,10 +485,7 @@ export default {
 
     handleSortChange(sort) {
       this.sort = sort;
-      this.fetchPagedFeatures({
-        filterType: undefined,
-        filterValue: undefined,
-      });
+      this.fetchPagedFeatures();
     },
 
     toPage(pageNumber) {
diff --git a/src/views/Project/ProjectDetail.vue b/src/views/Project/ProjectDetail.vue
index 54b5a96c7c5902cecb74199e39d0ff6868a3fab7..af54519200e6519cd5db9bea736bb430a4651868 100644
--- a/src/views/Project/ProjectDetail.vue
+++ b/src/views/Project/ProjectDetail.vue
@@ -389,42 +389,51 @@ export default {
       this.featureTypeToDelete = featureType;
       this.OPEN_PROJECT_MODAL('deleteFeatureType');
     },
-
+    /**
+     * Initializes the map if the project is accessible and the user has view permissions.
+     * This method sets up the map, loads vector tile layers, and handles offline features.
+     */
     async initMap() {
+      // Check if the project is accessible and the user has view permissions
       if (this.project && this.permissions.can_view_project) {
+        // Initialize the map using the provided element reference
         await this.INITIATE_MAP({ el: this.$refs.map });
+        // Check for offline features
         this.checkForOfflineFeature();
+        // Define the URL for vector tile layers
         const mvtUrl = `${this.API_BASE_URL}features.mvt`;
-        mapService.addVectorTileLayer({
-          url: mvtUrl,
+        // Define parameters for loading layers
+        const params = {
           project_slug: this.slug,
           featureTypes: this.feature_types,
           queryParams: {
             ordering: this.project.feature_browsing_default_sort,
             filter: this.project.feature_browsing_default_filter,
-          }
+          },
+        };
+        // Add vector tile layers to the map
+        mapService.addVectorTileLayer({
+          url: mvtUrl,
+          ...params
         });
-
+        // Modify offline feature properties (setting color to 'red')
         this.arraysOffline.forEach((x) => (x.geojson.properties.color = 'red'));
+        // Extract offline features from arraysOffline
         const featuresOffline = this.arraysOffline.map((x) => x.geojson);
+        // Add offline features to the map if available
         if (featuresOffline && featuresOffline.length > 0) {
           mapService.addFeatures({
             addToMap: true,
-            project_slug: this.slug,
             features: featuresOffline,
-            featureTypes: this.feature_types,
-            queryParams: {
-              ordering: this.project.feature_browsing_default_sort,
-              filter: this.project.feature_browsing_default_filter,
-            },
+            ...params
           });
         }
-        
+        // Get the bounding box of features and fit the map to it
         featureAPI.getFeaturesBbox(this.slug).then((bbox) => {
           if (bbox) {
             mapService.fitBounds(bbox);
           }
-          this.mapLoading = false;
+          this.mapLoading = false; // Mark map loading as complete
         });
       }
     },