From e38ac9a343dca4a5cdc15b255b287473c26c6c8e Mon Sep 17 00:00:00 2001
From: Rémy Raes <contact@remyraes.com>
Date: Fri, 14 Apr 2023 11:14:55 +0200
Subject: feat: Filter PRs (#264)

* feat: add input elements to collapse headers

* feat: filter pull requests regarding input content

* fix: cast PR titles to lowercase to match uppercase words

* feat: display a message if there's no matching PRs
---
 src-vue/src/components/PullRequestsSelector.vue | 75 +++++++++++++++++++++++--
 1 file changed, 70 insertions(+), 5 deletions(-)

(limited to 'src-vue/src/components/PullRequestsSelector.vue')

diff --git a/src-vue/src/components/PullRequestsSelector.vue b/src-vue/src/components/PullRequestsSelector.vue
index a7165cf6..ba95624a 100644
--- a/src-vue/src/components/PullRequestsSelector.vue
+++ b/src-vue/src/components/PullRequestsSelector.vue
@@ -1,7 +1,12 @@
 <template>
     <div>
         <el-collapse @change="onChange">
-            <el-collapse-item title="Launcher PRs" name="1">
+            <el-collapse-item name="1">
+                <template #title>
+                    Launcher PRs
+                    <el-input class="pr_search_input" v-model="launcherSearch" placeholder="Filter pull requests" @click.stop="() =>  false"></el-input>
+                </template>
+
                 <p v-if="pull_requests_launcher.length === 0">
                     <el-progress
                         :show-text="false"
@@ -12,17 +17,28 @@
                         style="margin: 15px"
                     />
                 </p>
-                <el-card v-else shadow="hover" v-for="pull_request in pull_requests_launcher"
-                    v-bind:key="pull_request.url">
+                <el-card
+                    v-else-if="filtered_launcher_pull_requests.length !== 0"
+                    shadow="hover"
+                    v-for="pull_request in filtered_launcher_pull_requests"
+                    v-bind:key="pull_request.url"
+                >
                     <el-button type="primary" @click="installLauncherPR(pull_request)">Install</el-button>
                     <el-button type="primary" @click="downloadLauncherPR(pull_request)">Download</el-button>
                     <a target="_blank" :href="pull_request.html_url">
                         {{ pull_request.number }}: {{ pull_request.title }}
                     </a>
                 </el-card>
+                <div v-else class="no_matching_pr">
+                    No matching PR found.
+                </div>
             </el-collapse-item>
 
-            <el-collapse-item title="Mods PRs" name="2">
+            <el-collapse-item name="2">
+                <template #title>
+                    Mods PRs
+                    <el-input class="pr_search_input" v-model="modsSearch" placeholder="Filter pull requests" @click.stop="() =>  false"></el-input>
+                </template>
                 <div style="margin: 15px">
                     <el-alert title="Warning" type="warning" :closable="false" show-icon>
                         Mod PRs are installed into a separate profile. Make sure to launch via
@@ -40,13 +56,21 @@
                         style="margin: 15px"
                     />
                 </p>
-                <el-card v-else shadow="hover" v-for="pull_request in pull_requests_mods" v-bind:key="pull_request.url">
+                <el-card
+                    v-else-if="filtered_mods_pull_requests.length !== 0"
+                    shadow="hover"
+                    v-for="pull_request in filtered_mods_pull_requests"
+                    v-bind:key="pull_request.url"
+                >
                     <el-button type="primary" @click="installModsPR(pull_request)">Install</el-button>
                     <el-button type="primary" @click="downloadModsPR(pull_request)">Download</el-button>
                     <a target="_blank" :href="pull_request.html_url">
                         {{ pull_request.number }}: {{ pull_request.title }}
                     </a>
                 </el-card>
+                <div v-else class="no_matching_pr">
+                    No matching PR found.
+                </div>
             </el-collapse-item>
         </el-collapse>
     </div>
@@ -59,6 +83,10 @@ import { PullsApiResponseElement } from '../../../src-tauri/bindings/PullsApiRes
 
 export default defineComponent({
     name: 'PullRequestsSelector',
+    data: () => ({
+        launcherSearch: '',
+        modsSearch: ''
+    }),
     computed: {
         pull_requests_launcher(): PullsApiResponseElement[] {
             return this.$store.state.pullrequests.pull_requests_launcher;
@@ -66,6 +94,29 @@ export default defineComponent({
         pull_requests_mods(): PullsApiResponseElement[] {
             return this.$store.state.pullrequests.pull_requests_mods;
         },
+
+        filtered_launcher_pull_requests(): PullsApiResponseElement[] {
+            if (this.launcherSearch.length === 0) {
+                return this.pull_requests_launcher;
+            }
+
+            return this.pull_requests_launcher.filter(pr =>
+                // Check PR id
+                pr.number.toString().indexOf(this.launcherSearch) !== -1
+                // Check PR title
+                || pr.title.toLowerCase().indexOf(this.launcherSearch.toLowerCase()) !== -1);
+        },
+        filtered_mods_pull_requests(): PullsApiResponseElement[] {
+            if (this.modsSearch.length === 0) {
+                return this.pull_requests_mods;
+            }
+
+            return this.pull_requests_mods.filter(pr =>
+                // Check PR id
+                pr.number.toString().indexOf(this.modsSearch) !== -1
+                // Check PR title
+                || pr.title.toLowerCase().indexOf(this.modsSearch.toLowerCase()) !== -1);
+        },
     },
     methods: {
         onChange(e: Object) {
@@ -106,4 +157,18 @@ export default defineComponent({
     padding-left: 10px;
     font-size: 14px;
 }
+
+.el-collapse:deep(.el-collapse-item__arrow) {
+    margin: 0 8px;
+}
+
+.pr_search_input {
+    width: 200px;
+    margin: 0 0 0 auto;
+}
+
+.no_matching_pr {
+    margin: 0 auto;
+    width: max-content;
+}
 </style>
-- 
cgit v1.2.3

