From 8351816e7d84e5f145b88e1e5ee93252156597b3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timoth=C3=A9e=20Poussard?= <tpoussard@neogeo.fr>
Date: Wed, 8 Dec 2021 15:12:02 +0100
Subject: [PATCH] use order from api & simplify filters code

---
 src/components/feature/FeatureListTable.vue |  80 ++-----
 src/views/feature/Feature_list.vue          | 234 +++++---------------
 2 files changed, 79 insertions(+), 235 deletions(-)

diff --git a/src/components/feature/FeatureListTable.vue b/src/components/feature/FeatureListTable.vue
index 7b360361..db7b252a 100644
--- a/src/components/feature/FeatureListTable.vue
+++ b/src/components/feature/FeatureListTable.vue
@@ -75,7 +75,7 @@
         </tr>
       </thead>
       <tbody>
-        <tr v-for="(feature, index) in sortedFeatures" :key="index">
+        <tr v-for="(feature, index) in paginatedFeatures" :key="index">
           <td class="center">
             <div
               class="ui checkbox"
@@ -240,18 +240,9 @@ export default {
     "checkedFeatures",
     "featuresCount",
     "pagination",
-    "pageNumbers",
+    "sort",
   ],
 
-  data() {
-    return {
-      sort: {
-        column: "",
-        ascending: true,
-      },
-    };
-  },
-
   computed: {
     ...mapState(["user"]),
     ...mapGetters(["project", "permissions"]),
@@ -260,50 +251,6 @@ export default {
       return this.permissions.is_project_administrator;
     },
 
-    sortedFeatures() {
-      let sortedFeatures = [...this.paginatedFeatures];
-      // Ajout du tri
-      if (this.sort.column !== "") {
-        sortedFeatures = sortedFeatures.sort((a, b) => {
-          let aProp = this.getFeatureDisplayName(a);
-          let bProp = this.getFeatureDisplayName(b);
-          if (this.sort.column === "status") {
-            aProp = a.properties.status.value;
-            bProp = b.properties.status.value;
-          } else if (this.sort.column === "feature_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;
-            }
-            if (aProp > bProp) {
-              return 1;
-            }
-            return 0;
-          } else {
-            //descending
-            if (aProp < bProp) {
-              return 1;
-            }
-            if (aProp > bProp) {
-              return -1;
-            }
-            return 0;
-          }
-        });
-      }
-      return sortedFeatures;
-    },
-
     checked: {
       get() {
         return this.checkedFeatures;
@@ -313,6 +260,16 @@ export default {
       },
     },
 
+    pageNumbers() {
+      const totalPages = Math.ceil(
+        this.featuresCount / this.pagination.pagesize
+      );
+      return [...Array(totalPages).keys()].map((pageNumb) => {
+        ++pageNumb;
+        return pageNumb;
+      });
+    },
+
     displayedPageEnd() {
       return this.featuresCount <= this.pagination.end
         ? this.featuresCount
@@ -341,15 +298,18 @@ export default {
     changeSort(column) {
       if (this.sort.column === column) {
         //changer order
-        this.sort.ascending = !this.sort.ascending;
+        this.$emit(
+          "update:sort",
+          { column: this.sort.column, ascending: !this.sort.ascending }
+        );
       } else {
         this.sort.column = column;
         this.sort.ascending = true;
+        this.$emit(
+          "update:sort",
+          { column, ascending: true }
+        );
       }
-      this.$emit(
-        "update:sort",
-        `${this.sort.ascending ? "-" : ""}${this.sort.column}`
-      );
     },
   },
 };
diff --git a/src/views/feature/Feature_list.vue b/src/views/feature/Feature_list.vue
index f8b6d5f6..c31ad087 100644
--- a/src/views/feature/Feature_list.vue
+++ b/src/views/feature/Feature_list.vue
@@ -86,7 +86,6 @@
       <div class="field wide four column no-margin-mobile">
         <label>Type</label>
         <Dropdown
-          v-on:update:selection="updateTypeFeatures"
           :options="featureTypeChoices"
           :selected="form.type.selected"
           :selection.sync="form.type.selected"
@@ -98,7 +97,6 @@
         <label>Statut</label>
         <!--  //* giving an object mapped on key name -->
         <Dropdown
-          v-on:update:selection="updateStatusFeatures"
           :options="statusChoices"
           :selected="form.status.selected.name"
           :selection.sync="form.status.selected"
@@ -146,7 +144,7 @@
       :checkedFeatures.sync="checkedFeatures"
       :featuresCount="featuresCount"
       :pagination="pagination"
-      :pageNumbers="pageNumbers"
+      :sort="sort"
     />
 
     <!-- MODAL ALL DELETE FEATURE TYPE -->
@@ -202,17 +200,12 @@ export default {
 
   data() {
     return {
-      modalAllDeleteOpen: false,
       form: {
         type: {
-          selected: null,
-          choices: [],
+          selected: "",
         },
         status: {
-          selected: {
-            name: null,
-            value: null,
-          },
+          selected: "",
           choices: [
             {
               name: "Brouillon",
@@ -234,33 +227,40 @@ export default {
         },
         title: null,
       },
-      filters: {
-        type: "",
-        value: "",
-      },
-      filtersBis: {},
-      paginatedFeatures: [],
       baseUrl: this.$store.state.configuration.BASE_URL,
+      modalAllDeleteOpen: false,
       map: null,
       zoom: null,
       lat: null,
       lng: null,
       featuresCount: 0,
-      next: null,
-      previous: null,
-      paginateUrl: null,
+      paginatedFeatures: [],
       pagination: {
         currentPage: 1,
         pagesize: 15,
         start: 0,
         end: 15,
       },
-      //showMap: true,
-      showMap: false,
+      previous: null,
+      next: null,
+      sort: {
+        column: "",
+        ascending: true,
+      },
+      showMap: true,
       showAddFeature: false,
     };
   },
 
+  watch: {
+    "form.type.selected"() {
+      this.fetchPagedFeatures();
+    },
+    "form.status.selected.value"() {
+      this.fetchPagedFeatures();
+    },
+  },
+
   computed: {
     ...mapGetters(["project", "permissions"]),
     ...mapState("feature", ["checkedFeatures"]),
@@ -281,16 +281,6 @@ export default {
     featureTypeChoices() {
       return this.feature_types.map((el) => el.title);
     },
-
-    pageNumbers() {
-      const totalPages = Math.ceil(
-        this.featuresCount / this.pagination.pagesize
-      );
-      return [...Array(totalPages).keys()].map((pageNumb) => {
-        ++pageNumb;
-        return pageNumb;
-      });
-    },
   },
 
   methods: {
@@ -357,7 +347,7 @@ export default {
         mapDefaultViewZoom,
       });
 
-      this.getBbox2FIt();
+      this.fetchBboxNfit();
 
       document.addEventListener("change-layers-order", (event) => {
         // Reverse is done because the first layer in order has to be added in the map in last.
@@ -380,7 +370,7 @@ export default {
       }, 1000);
     },
 
-    getBbox2FIt(queryParams) {
+    fetchBboxNfit(queryParams) {
       featureAPI
         .getFeaturesBbox(this.project.slug, queryParams)
         .then((bbox) => {
@@ -396,153 +386,42 @@ export default {
       return featureType ? featureType.slug : null;
     },
 
-    buildFilterParams(params) {
-      const { filterType, filterValue } = params;
-      let urlParams = "";
-      let typeFilter, statusFilter;
-      console.log(filterType, filterValue);
-      //*** feature type ***//
-      if (filterType === "featureType") {
-        if (filterValue === "" && !this.form.type.selected) {
-          //* s'il y n'avait pas de filtre et qu'il a été supprimé --> ne pas mettre à jour les features
-          return "abort";
-        } else if (filterValue !== undefined && filterValue !== null) {
-          //* s'il y a un nouveau filtre --> ajouter une params
-          typeFilter = this.getFeatureTypeSlug(filterValue);
-        } //* sinon il n'y a pas de param ajouté, ce qui supprime la query
-
-        //*** status ***//
-      } else if (filterType === "status") {
-        if (filterValue === "" && !this.form.status.selected.value) {
-          return "abort";
-        } else if (filterValue !== undefined && filterValue !== null) {
-          statusFilter = filterValue;
-          //statusFilter = filterValue.value;
-        }
-      }
-
-      //* after possibilities of aborting features fetch, empty geojson to make sure even no result would update
-
-      if (
-        (filterType === undefined || filterType === "status") &&
-        this.form.type.selected
-      ) {
-        //* s'il y a déjà un filtre sélectionné, maintenir le params
-        typeFilter = this.getFeatureTypeSlug(this.form.type.selected);
-      }
-      if (
-        (filterType === undefined || filterType === "featureType") &&
-        this.form.status.selected.value
-      ) {
-        statusFilter = this.form.status.selected.value;
+    getAvalaibleField(orderField) {
+      let result = orderField;
+      if (orderField === "display_creator") {
+        result = "creator";
+      } else if (orderField === "display_last_editor") {
+        result = "last_editor";
       }
-
-      if (typeFilter) {
-        let typeParams = `&feature_type_slug=${typeFilter}`;
-        urlParams += typeParams;
-      }
-      if (statusFilter) {
-        let statusParams = `&status__value=${statusFilter}`;
-        urlParams += statusParams;
-      }
-
-      //*** title ***//
-      if (this.form.title) {
-        urlParams += `&title=${this.form.title}`;
-      }
-      this.getBbox2FIt(urlParams);
-      return urlParams;
+      return result;
     },
 
-    /*     buildFilterParamsBis() {
-      let params = "";
-      let typeFilter, statusFilter;
-
-      if ("featureType") {
-        if (filterValue === "" && !this.form.type.selected) {
-          //* s'il y n'avait pas de filtre et qu'il a été supprimé --> ne pas mettre à jour les features
-          return "abort";
-        } else if (filterValue !== undefined && filterValue !== null) {
-          //* s'il y a un nouveau filtre --> ajouter une params
-          typeFilter = this.getFeatureTypeSlug(filterValue);
-        } //* sinon il n'y a pas de param ajouté, ce qui supprime la query
-
-
-      } else if (filterType === "status") {
-        if (filterValue === "" && !this.form.status.selected.value) {
-          return "abort";
-        } else if (filterValue !== undefined && filterValue !== null) {
-          statusFilter = filterValue.value;
-        }
-      }
-
-      //* after possibilities of aborting features fetch, empty geojson to make sure even no result would update
-
-      if (
-        (filterType === undefined || filterType === "status") &&
-        this.form.type.selected
-      ) {
-        //* s'il y a déjà un filtre sélectionné, maintenir le params
-        typeFilter = this.getFeatureTypeSlug(this.form.type.selected);
-      }
-      if (
-        (filterType === undefined || filterType === "featureType") &&
-        this.form.status.selected.value
-      ) {
-        statusFilter = this.form.status.selected.value;
-      }
-
-      if (typeFilter) {
-        let typeParams = `&feature_type_slug=${typeFilter}`;
-        params += typeParams;
-      }
-      if (statusFilter) {
-        let statusParams = `&status__value=${statusFilter}`;
-        params += statusParams;
-      }
-
-
-      if (this.form.title) {
-        params += `&title=${this.form.title}`;
+    buildQueryString() {
+      let urlParams = "";
+      let typeFilter = this.getFeatureTypeSlug(this.form.type.selected);
+      let statusFilter = this.form.status.selected.value;
+
+      if (typeFilter) urlParams += `&feature_type_slug=${typeFilter}`;
+      if (statusFilter) urlParams += `&status__value=${statusFilter}`;
+      if (this.form.title) urlParams += `&title=${this.form.title}`;
+      if (this.sort.column) {
+        urlParams += `&ordering=${
+          this.sort.ascending ? "-" : ""
+        }${this.getAvalaibleField(this.sort.column)}`;
       }
-      this.getBbox2FIt(params);
-      return params;
-    }, */
-
-    updateTypeFeatures(filterValue) {
-      //* only update:selection custom event can trigger the filter update,
-      //* but it happens before the value is updated, thus using selected value from event to update query
-      this.fetchPagedFeatures({ filterType: "featureType", filterValue });
-      //this.filters = { type: "featureType", value };
-      //this.filtersBis["featureType"] = value;
-      //this.fetchPagedFeatures();
-    },
-
-    updateStatusFeatures(filterValue) {
-      this.fetchPagedFeatures({
-        filterType: "status",
-        filterValue: filterValue.value,
-      });
-      //this.filtersBis["status"] = value;
-      //this.filters = { type: "status", value };
-      //this.fetchPagedFeatures();
+      return urlParams;
     },
 
-    fetchPagedFeatures(params) {
-      this.onFilterChange(); //* temporary, use paginated event to watch change in filters, to modify geojson on map
+    fetchPagedFeatures(newUrl) {
+      this.onFilterChange(); //* use paginated event to watch change in filters and modify features on map
       let url = `${this.API_BASE_URL}projects/${this.$route.params.slug}/feature-paginated/?output=geojson&limit=${this.pagination.pagesize}&offset=${this.pagination.start}`;
-        //console.log(this.buildFilterParamsBis(params))
-      if (typeof params === "string") { //* for receiving next & previous url
-        //console.error("ONLY FOR DEV !!!!!!!!!!!!!");
-        //params = params.replace("8000", "8010"); //* for dev uncomment to use proxy link
-        url = params;
-      } else if (typeof params === "object") {
-        const filterParams = this.buildFilterParams(params);
-        if (filterParams === "abort") return; // ? to adapt ???
-        url += filterParams;
-        console.log("filterParams", filterParams);
+      if (newUrl && typeof newUrl === "string") {
+        //* if receiving next & previous url
+        //newUrl = newUrl.replace("8000", "8010"); //* for dev uncomment to use proxy link
+        url = newUrl;
       }
-     // this.paginateUrl = url; //* store to reuse with sorting
+      const queryString = this.buildQueryString();
+      url += queryString;
 
       this.$store.commit(
         "DISPLAY_LOADER",
@@ -555,6 +434,8 @@ export default {
           this.next = data.next;
           this.paginatedFeatures = data.results.features;
         }
+        //* bbox needs to be updated with the same filters
+        if (queryString) this.fetchBboxNfit(queryString);
         this.$store.commit("DISCARD_LOADER");
       });
     },
@@ -572,9 +453,12 @@ export default {
       }
     },
 
-    handleSortChange(ordering) {
-      console.log("ORDERING", ordering);
-      this.fetchPagedFeatures({filterType: undefined, filterValue: undefined})
+    handleSortChange(sort) {
+      this.sort = sort;
+      this.fetchPagedFeatures({
+        filterType: undefined,
+        filterValue: undefined,
+      });
     },
 
     toPage(pageNumber) {
-- 
GitLab