From 98a55a2a3f6f6c831f1bb3474035cc95698fc39c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timoth=C3=A9e=20Poussard?= <tpoussard@neogeo.fr>
Date: Thu, 3 Mar 2022 19:40:23 +0100
Subject: [PATCH] fix offline put not working & create service to post or put
 features

---
 src/services/feature-api.js          | 76 ++++++++++++++++++----------
 src/store/modules/feature.store.js   |  6 ++-
 src/views/project/Project_detail.vue | 76 ++++++++++------------------
 3 files changed, 79 insertions(+), 79 deletions(-)

diff --git a/src/services/feature-api.js b/src/services/feature-api.js
index a2278387..690df05e 100644
--- a/src/services/feature-api.js
+++ b/src/services/feature-api.js
@@ -62,6 +62,55 @@ const featureAPI = {
     }
   },
 
+  async getFeatureLinks(featureId) {
+    const response = await axios.get(
+      `${baseUrl}features/${featureId}/feature-links/`
+    );
+    if (
+      response.status === 200 &&
+      response.data
+    ) {
+      return response.data;
+    } else {
+      return null;
+    }
+  },
+
+  async getFeaturesBlob(url) {
+    const response = await axios
+      .get(url, { responseType: 'blob' });
+    if (
+      response.status === 200 &&
+      response.data
+    ) {
+      return response.data;
+    } else {
+      return null;
+    }
+  },
+  // todo : fonction pour faire un post ou un put du signalement
+
+
+  async postOrPutFeature({ method, feature_id, feature_type__slug, project__slug, data }) {
+    let url = `${baseUrl}features/`;
+    if (method === 'PUT') {
+      url += `${feature_id}/?
+      feature_type__slug=${feature_type__slug}
+      &project__slug=${project__slug}`;
+    }
+
+    const response = await axios({
+      url,
+      method,
+      data,
+    });
+    if ((response.status === 200 || response.status === 201) && response.data) {
+      return response;
+    } else {
+      return null;
+    }
+  },
+
   async updateFeature({ feature_id, feature_type__slug, project__slug, newStatus }) {
     let url = `${baseUrl}features/${feature_id}/?feature_type__slug=${feature_type__slug}&project__slug=${project__slug}`;
 
@@ -108,33 +157,6 @@ const featureAPI = {
       return null;
     }
   },
-
-  async getFeatureLinks(featureId) {
-    const response = await axios.get(
-      `${baseUrl}features/${featureId}/feature-links/`
-    );
-    if (
-      response.status === 200 &&
-      response.data
-    ) {
-      return response.data;
-    } else {
-      return null;
-    }
-  },
-
-  async getFeaturesBlob(url) {
-    const response = await axios
-      .get(url, { responseType: 'blob' });
-    if (
-      response.status === 200 &&
-      response.data
-    ) {
-      return response.data;
-    } else {
-      return null;
-    }
-  },
 };
 
 export default featureAPI;
diff --git a/src/store/modules/feature.store.js b/src/store/modules/feature.store.js
index 3039126b..3f8052d8 100644
--- a/src/store/modules/feature.store.js
+++ b/src/store/modules/feature.store.js
@@ -1,7 +1,6 @@
 import axios from '@/axios-client.js';
 import router from '../../router';
 
-
 const feature = {
   namespaced: true,
   state: {
@@ -235,6 +234,9 @@ const feature = {
         &project__slug=${rootState.projects.project.slug}`;
       }
 
+      //* postOrPutFeature function from service featureAPI could be used here, but because configuration is in store,
+      //* projectBase would need to be sent with each function which imply to modify all function from this service,
+      //* which could create regression
       return axios({
         url,
         method: routeName === 'editer-signalement' ? 'PUT' : 'POST',
@@ -252,7 +254,7 @@ const feature = {
       })
         .catch((error) => {
           commit('DISCARD_LOADER', null, { root: true });
-          if (error.message === 'Network Error' || window.navigator.onLine === false) {
+          if (error.message === 'Network Error' || !rootState.isOnline) {
             let arraysOffline = [];
             let localStorageArray = localStorage.getItem('geocontrib_offline');
             if (localStorageArray) {
diff --git a/src/views/project/Project_detail.vue b/src/views/project/Project_detail.vue
index bb0e7e21..bab34be8 100644
--- a/src/views/project/Project_detail.vue
+++ b/src/views/project/Project_detail.vue
@@ -154,7 +154,7 @@
           <button
             :disabled="!isOnline"
             class="ui fluid labeled teal icon button"
-            @click="sendOfflineFeatures()"
+            @click="sendOfflineFeatures"
           >
             <i class="upload icon" />
             Envoyer au serveur
@@ -752,8 +752,6 @@ import projectAPI from '@/services/project-api';
 import featureTypeAPI from '@/services/featureType-api';
 import featureAPI from '@/services/feature-api';
 
-import axios from '@/axios-client.js';
-
 import { fileConvertSizeToMo } from '@/assets/js/utils';
 
 export default {
@@ -928,6 +926,8 @@ export default {
       'SET_RELOAD_INTERVAL_ID',
       'CLEAR_RELOAD_INTERVAL_ID',
       'DISPLAY_MESSAGE',
+      'DISPLAY_LOADER',
+      'DISCARD_LOADER',
     ]),
     ...mapActions('projects', [
       'GET_PROJECT_INFO',
@@ -976,13 +976,13 @@ export default {
     },
 
     retrieveProjectInfo() {
-      this.$store.commit('DISPLAY_LOADER', 'Projet en cours de chargement.');
+      this.DISPLAY_LOADER('Projet en cours de chargement.');
       Promise.all([
         this.GET_PROJECT(this.slug),
         this.GET_PROJECT_INFO(this.slug)
       ])
         .then(() => {
-          this.$store.commit('DISCARD_LOADER');
+          this.DISCARD_LOADER();
           this.projectInfoLoading = false;
           setTimeout(() => {
             let map = mapUtil.getMap();
@@ -992,14 +992,14 @@ export default {
         })
         .catch((err) => {
           console.error(err);
-          this.$store.commit('DISCARD_LOADER');
+          this.DISCARD_LOADER();
           this.projectInfoLoading = false;
         });
     },
 
     checkForOfflineFeature() {
       let arraysOffline = [];
-      let localStorageArray = localStorage.getItem('geocontrib_offline');
+      const localStorageArray = localStorage.getItem('geocontrib_offline');
       if (localStorageArray) {
         arraysOffline = JSON.parse(localStorageArray);
         this.arraysOffline = arraysOffline.filter(
@@ -1009,60 +1009,36 @@ export default {
     },
 
     sendOfflineFeatures() {
-      var promises = [];
-      let self = this;
       this.arraysOfflineErrors = [];
-      this.arraysOffline.forEach((feature) => {
-        if (feature.type === 'post') {
-          promises.push(
-            axios
-              .post(`${this.API_BASE_URL}features/`, feature.geojson)
-              .then((response) => {
-                if (response.status === 201 && response.data) {
-                  return 'OK';
-                } else {
-                  self.arraysOfflineErrors.push(feature);
-                }
-              })
-              .catch((error) => {
-                console.error(error);
-                self.arraysOfflineErrors.push(feature);
-              })
-          );
-        } else if (feature.type === 'put') {
-          promises.push(
-            axios
-              .put(
-                `${this.API_BASE_URL}features/${feature.featureId}`,
-                feature.geojson
-              )
-              .then((response) => {
-                if (response.status === 200 && response.data) {
-                  return 'OK';
-                } else {
-                  self.arraysOfflineErrors.push(feature);
-                }
-              })
-              .catch((error) => {
-                console.error(error);
-                self.arraysOfflineErrors.push(feature);
-              })
-          );
-        }
-      });
+      const promises = this.arraysOffline.map((feature) => featureAPI.postOrPutFeature({
+        data: feature.geojson,
+        feature_id: feature.featureId,
+        project__slug: feature.project,
+        feature_type__slug: feature.geojson.properties.feature_type,
+        method: feature.type.toUpperCase(),
+      })
+        .then((response) => {
+          if (!response) this.arraysOfflineErrors.push(feature);
+        })
+        .catch((error) => {
+          console.error(error);
+          this.arraysOfflineErrors.push(feature);
+        })
+      );
+      this.DISPLAY_LOADER('Envoi des signalements en cours.');
       Promise.all(promises).then(() => {
         this.updateLocalStorage();
-        window.location.reload();
+        this.retrieveProjectInfo();
       });
     },
 
     updateLocalStorage() {
       let arraysOffline = [];
-      let localStorageArray = localStorage.getItem('geocontrib_offline');
+      const localStorageArray = localStorage.getItem('geocontrib_offline');
       if (localStorageArray) {
         arraysOffline = JSON.parse(localStorageArray);
       }
-      let arraysOfflineOtherProject = arraysOffline.filter(
+      const arraysOfflineOtherProject = arraysOffline.filter(
         (x) => x.project !== this.slug
       );
       this.arraysOffline = [];
-- 
GitLab