From 25acd6c822e0122e6cc9fc49e229100e5376fc06 Mon Sep 17 00:00:00 2001
From: Morlinest <morlinest@gmail.com>
Date: Wed, 1 Nov 2017 20:39:05 +0100
Subject: [PATCH] Use custom search for each filter type in dashboard (#2343)

* Do custom search for each filter in repo-search

* Fix search url

* Simplify code

* Remove loader and reset counts when changing filter
---
 public/js/index.js                      | 64 ++++++++++++++++++++-----
 templates/user/dashboard/dashboard.tmpl | 29 ++++++++---
 2 files changed, 74 insertions(+), 19 deletions(-)

diff --git a/public/js/index.js b/public/js/index.js
index 259980c3ca..b6438f296f 100644
--- a/public/js/index.js
+++ b/public/js/index.js
@@ -1671,12 +1671,46 @@ function initVueComponents(){
                 reposTotalCount: 0,
                 reposFilter: 'all',
                 searchQuery: '',
-                isLoading: false
+                isLoading: false,
+                repoTypes: {
+                    'all': {
+                        count: 0,
+                        searchMode: '',
+                    },
+                    'forks': {
+                        count: 0,
+                        searchMode: 'fork',
+                    },
+                    'mirrors': {
+                        count: 0,
+                        searchMode: 'mirror',
+                    },
+                    'sources': {
+                        count: 0,
+                        searchMode: 'source',
+                    },
+                    'collaborative': {
+                        count: 0,
+                        searchMode: 'collaborative',
+                    },
+                }
+            }
+        },
+
+        computed: {
+            showMoreReposLink: function() {
+                return this.repos.length > 0 && this.repos.length < this.repoTypes[this.reposFilter].count;
+            },
+            searchURL: function() {
+                return this.suburl + '/api/v1/repos/search?uid=' + this.uid + '&q=' + this.searchQuery + '&limit=' + this.searchLimit + '&mode=' + this.repoTypes[this.reposFilter].searchMode + (this.reposFilter !== 'all' ? '&exclusive=1' : '');
+            },
+            repoTypeCount: function() {
+                return this.repoTypes[this.reposFilter].count;
             }
         },
 
         mounted: function() {
-            this.searchRepos();
+            this.searchRepos(this.reposFilter);
 
             var self = this;
             Vue.nextTick(function() {
@@ -1691,6 +1725,9 @@ function initVueComponents(){
 
             changeReposFilter: function(filter) {
                 this.reposFilter = filter;
+                this.repos = [];
+                this.repoTypes[filter].count = 0;
+                this.searchRepos(filter);
             },
 
             showRepo: function(repo, filter) {
@@ -1708,28 +1745,31 @@ function initVueComponents(){
                 }
             },
 
-            searchRepos: function() {
+            searchRepos: function(reposFilter) {
                 var self = this;
+
                 this.isLoading = true;
+
+                var searchedMode = this.repoTypes[reposFilter].searchMode;
+                var searchedURL = this.searchURL;
                 var searchedQuery = this.searchQuery;
-                $.getJSON(this.searchURL(), function(result, textStatus, request) {
-                    if (searchedQuery == self.searchQuery) {
+
+                $.getJSON(searchedURL, function(result, textStatus, request) {
+                    if (searchedURL == self.searchURL) {
                         self.repos = result.data;
-                        if (searchedQuery == "") {
-                            self.reposTotalCount = request.getResponseHeader('X-Total-Count');
+                        var count = request.getResponseHeader('X-Total-Count');
+                        if (searchedQuery === '' && searchedMode === '') {
+                            self.reposTotalCount = count;
                         }
+                        self.repoTypes[reposFilter].count = count;
                     }
                 }).always(function() {
-                    if (searchedQuery == self.searchQuery) {
+                    if (searchedURL == self.searchURL) {
                         self.isLoading = false;
                     }
                 });
             },
 
-            searchURL: function() {
-                return this.suburl + '/api/v1/repos/search?uid=' + this.uid + '&q=' + this.searchQuery + '&limit=' + this.searchLimit;
-            },
-
             repoClass: function(repo) {
                 if (repo.fork) {
                     return 'octicon octicon-repo-forked';
diff --git a/templates/user/dashboard/dashboard.tmpl b/templates/user/dashboard/dashboard.tmpl
index 8204c0b7e7..2ad4008bbf 100644
--- a/templates/user/dashboard/dashboard.tmpl
+++ b/templates/user/dashboard/dashboard.tmpl
@@ -43,15 +43,30 @@
 							</h4>
 							<div class="ui attached secondary segment repos-search">
 								<div class="ui fluid icon input" :class="{loading: isLoading}">
-									<input @input="searchRepos" v-model="searchQuery" ref="search" placeholder="{{.i18n.Tr "home.search_repos"}}">
+									<input @input="searchRepos(reposFilter)" v-model="searchQuery" ref="search" placeholder="{{.i18n.Tr "home.search_repos"}}">
 									<i class="search icon"></i>
 								</div>
 								<div class="ui secondary tiny pointing borderless menu center aligned grid repos-filter">
-									<a class="item" :class="{active: reposFilter === 'all'}" @click="changeReposFilter('all')">{{.i18n.Tr "all"}}</a>
-									<a class="item" :class="{active: reposFilter === 'sources'}" @click="changeReposFilter('sources')">{{.i18n.Tr "sources"}}</a>
-									<a class="item" :class="{active: reposFilter === 'forks'}" @click="changeReposFilter('forks')">{{.i18n.Tr "forks"}}</a>
-									<a class="item" :class="{active: reposFilter === 'mirrors'}" @click="changeReposFilter('mirrors')">{{.i18n.Tr "mirrors"}}</a>
-									<a class="item" :class="{active: reposFilter === 'collaborative'}" @click="changeReposFilter('collaborative')">{{.i18n.Tr "collaborative"}}</a>
+									<a class="item" :class="{active: reposFilter === 'all'}" @click="changeReposFilter('all')">
+										{{.i18n.Tr "all"}}
+										<div v-show="reposFilter === 'all'" class="ui circular mini grey label">${repoTypeCount}</div>
+									</a>
+									<a class="item" :class="{active: reposFilter === 'sources'}" @click="changeReposFilter('sources')">
+										{{.i18n.Tr "sources"}}
+										<div v-show="reposFilter === 'sources'" class="ui circular mini grey label">${repoTypeCount}</div>
+									</a>
+									<a class="item" :class="{active: reposFilter === 'forks'}" @click="changeReposFilter('forks')">
+										{{.i18n.Tr "forks"}}
+										<div v-show="reposFilter === 'forks'" class="ui circular mini grey label">${repoTypeCount}</div>
+									</a>
+									<a class="item" :class="{active: reposFilter === 'mirrors'}" @click="changeReposFilter('mirrors')">
+										{{.i18n.Tr "mirrors"}}
+										<div v-show="reposFilter === 'mirrors'" class="ui circular mini grey label">${repoTypeCount}</div>
+									</a>
+									<a class="item" :class="{active: reposFilter === 'collaborative'}" @click="changeReposFilter('collaborative')">
+										{{.i18n.Tr "collaborative"}}
+										<div v-show="reposFilter === 'collaborative'" class="ui circular mini grey label">${repoTypeCount}</div>
+									</a>
 								</div>
 							</div>
 							<div class="ui attached table segment">
@@ -65,7 +80,7 @@
 											</span>
 										</a>
 									</li>
-									<li v-if="repos.length < reposTotalCount">
+									<li v-if="showMoreReposLink">
 										<a :href="moreReposLink">{{.i18n.Tr "home.show_more_repos"}}</a>
 									</li>
 								</ul>