From f6cd8aaba6726b9fedb7c432583107715ca5fe6e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timoth=C3=A9e=20Poussard?= <tpoussard@neogeo.fr>
Date: Fri, 1 Sep 2023 13:23:40 +0200
Subject: [PATCH] add filtered-feature-detail router in user page

---
 src/components/Account/UserActivity.vue       | 76 ++++++++++---------
 .../Feature/FeatureFetchOffsetRoute.vue       | 68 +++++++++++------
 2 files changed, 83 insertions(+), 61 deletions(-)

diff --git a/src/components/Account/UserActivity.vue b/src/components/Account/UserActivity.vue
index f6e8b18a..ec8f8ce6 100644
--- a/src/components/Account/UserActivity.vue
+++ b/src/components/Account/UserActivity.vue
@@ -38,19 +38,17 @@
                 </div>
 
                 <div v-else>
-                  <router-link
+                  <FeatureFetchOffsetRoute
                     v-if="item.related_feature.deletion_on === 'None'"
-                    :to="{
-                      name: 'details-signalement',
-                      params: {
-                        slug: item.project_slug,
-                        slug_type_signal: item.feature_type_slug,
-                        slug_signal: item.feature_id,
-                      }
+                    :feature-id="item.feature_id"
+                    :properties="{
+                      feature_type: {
+                        slug: item.feature_type_slug
+                      },
+                      title: item.related_feature.title,
+                      ...item
                     }"
-                  >
-                    {{ item.related_feature.title }}
-                  </router-link>
+                  />
                   <span
                     v-else
                     class="meta"
@@ -90,20 +88,17 @@
             >
               <div class="content">
                 <div>
-                  <router-link
+                  <FeatureFetchOffsetRoute
                     v-if="item.related_feature.deletion_on === 'None'"
-                    :to="{
-                      name: 'details-signalement',
-                      params: {
-                        slug: item.project_slug,
-                        slug_type_signal: item.feature_type_slug,
-                        slug_signal: item.feature_id,
-                      }
+                    :feature-id="item.feature_id"
+                    :properties="{
+                      feature_type: {
+                        slug: item.feature_type_slug
+                      },
+                      title: item.related_feature.title,
+                      ...item
                     }"
-                  >
-                    {{ item.related_feature.title }}
-                  </router-link>
-
+                  />
                   <span
                     v-else
                     class="meta"
@@ -144,20 +139,17 @@
             >
               <div class="content">
                 <div>
-                  <router-link
+                  <FeatureFetchOffsetRoute
                     v-if="item.related_feature.deletion_on === 'None'"
-                    :to="{
-                      name: 'details-signalement',
-                      params: {
-                        slug: item.project_slug,
-                        slug_type_signal: item.feature_type_slug,
-                        slug_signal: item.feature_id,
-                      }
+                    :feature-id="item.feature_id"
+                    :properties="{
+                      feature_type: {
+                        slug: item.feature_type_slug
+                      },
+                      title: quoteComment(item.data.comment),
+                      ...item
                     }"
-                  >
-                    "{{ item.data.comment }}"
-                  </router-link>
-
+                  />
                   <span
                     v-else
                     class="meta"
@@ -190,11 +182,15 @@
 import { mapState } from 'vuex';
 
 import miscAPI from '@/services/misc-api';
+import FeatureFetchOffsetRoute from '@/components/Feature/FeatureFetchOffsetRoute';
 
 export default {
-
   name: 'UserActivity',
 
+  components: {
+    FeatureFetchOffsetRoute,
+  },
+
   data() {
     return {
       events: [],
@@ -215,6 +211,8 @@ export default {
 
   created(){
     this.getEvents();
+    // unset project to avoid interfering with generating query in feature links 
+    this.$store.commit('projects/SET_PROJECT', null);
   },
 
   methods: {
@@ -253,7 +251,11 @@ export default {
           return 'Événement inconnu';
         }
       }
-    }
+    },
+
+    quoteComment(comment) {
+      return `"${comment}"`;
+    },
   }
 
 };
diff --git a/src/components/Feature/FeatureFetchOffsetRoute.vue b/src/components/Feature/FeatureFetchOffsetRoute.vue
index 8dc8363d..2585854c 100644
--- a/src/components/Feature/FeatureFetchOffsetRoute.vue
+++ b/src/components/Feature/FeatureFetchOffsetRoute.vue
@@ -3,9 +3,7 @@
     :is="position >= 0 ? 'router-link' : 'span'"
     :to="{
       name: 'details-signalement-filtre',
-      params: {
-        slug_type_signal: properties.feature_type.slug,
-      },
+      params: { slug },
       query,
     }"
   >
@@ -18,6 +16,8 @@
 import { mapState } from 'vuex';
 import axios from '@/axios-client.js';
 
+import projectAPI from '@/services/project-api';
+
 export default {
 
   name: 'FeatureFetchOffsetRoute',
@@ -30,13 +30,15 @@ export default {
     properties: {
       type: Object,
       default: () => {},
-    }
+    },
   },
 
   data() {
     return {
       position: null,
-      slug: this.$route.params.slug,
+      slug: this.$route.params.slug || this.properties.project_slug,
+      ordering: null,
+      filter: null,
     };
   },
   
@@ -45,33 +47,46 @@ export default {
       'project'
     ]),
     query() {
-      if (this.project) {
-        const searchParams = { ordering: this.project.feature_browsing_default_sort };
-        if (this.project.feature_browsing_default_filter === 'feature_type_slug') { // when feature_type is the default filter of the project, 
-          searchParams['feature_type_slug'] = this.properties.feature_type.slug; // get its slug for the current feature
-        }
-        if (this.position >= 0) {
-          searchParams['offset'] = this.position; // get its slug for the current feature
-        }
-        return searchParams;
+      const searchParams = { ordering: this.ordering };
+      if (this.filter === 'feature_type_slug') { // when feature_type is the default filter of the project, 
+        searchParams['feature_type_slug'] = this.properties.feature_type.slug; // get its slug for the current feature
       }
-      return {};
+      if (this.position >= 0) {
+        searchParams['offset'] = this.position; // get its slug for the current feature
+      }
+      return searchParams;
     },
   },
   
   created() {
-    this.getFeaturePosition(this.featureId)
-      .then((position) => {
-        if (position >= 0) {
-          this.position = position;
-        }
-      })
-      .catch((error) => {
-        console.error(error);
-      });
+    this.initData();
   },
 
   methods: {
+    async initData() {
+      if (this.project) {
+        this.setProjectParams(this.project);
+      } else {
+        await this.getProjectFilterAndSort();
+      }
+      this.getFeaturePosition(this.featureId)
+        .then((position) => {
+          if (position >= 0) {
+            this.position = position;
+          }
+        })
+        .catch((error) => {
+          console.error(error);
+        });
+    },
+
+    setProjectParams(project) {
+      this.ordering = project.feature_browsing_default_sort;
+      if (project.feature_browsing_default_filter === 'feature_type_slug') { // when feature_type is the default filter of the project, 
+        this.filter = this.properties.feature_type.slug;
+      }
+    },
+
     async getFeaturePosition(featureId) {
       const searchParams = new URLSearchParams(this.query);
       const response = await axios.get(`${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.slug}/feature/${featureId}/position-in-list/?${searchParams.toString()}`);
@@ -80,6 +95,11 @@ export default {
       }
       return null;
     },
+
+    async getProjectFilterAndSort() {
+      const project = await projectAPI.getProject(this.$store.state.configuration.VUE_APP_DJANGO_API_BASE, this.slug);
+      if (project) this.setProjectParams(project);
+    }
   }
 };
 </script>
-- 
GitLab