Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix and improve dashboard repo UI #2285

Merged
merged 7 commits into from
Aug 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ your_profile = Your Profile
your_starred = Your Starred
your_settings = Your Settings

all = All
sources = Sources
mirrors = Mirrors
collaborative = Collaborative

activities = Activities
pull_requests = Pull Requests
issues = Issues
Expand Down
11 changes: 11 additions & 0 deletions public/css/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,17 @@ footer .ui.language .menu {
padding-right: 30px !important;
}
}
[v-cloak] {
display: none !important;
}
.repos-search {
padding-bottom: 0 !important;
}
.repos-filter {
margin-top: 0 !important;
border-bottom-width: 0 !important;
margin-bottom: 2px !important;
}
.markdown:not(code) {
overflow: hidden;
font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
Expand Down
102 changes: 82 additions & 20 deletions public/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1655,29 +1655,45 @@ $(function () {
});
});

function initDashboardSearch() {
var el = document.getElementById('dashboard-repo-search');
if (!el) {
return;
}
function initVueComponents(){
var vueDelimeters = ['${', '}'];

new Vue({
delimiters: ['${', '}'],
el: el,
Vue.component('repo-search', {
delimiters: vueDelimeters,
template: '#repo-search-template',

data: {
tab: 'repos',
repos: [],
searchQuery: '',
suburl: document.querySelector('meta[name=_suburl]').content,
uid: document.querySelector('meta[name=_context_uid]').content
props: {
searchLimit: {
type: Number,
default: 10
},
suburl: {
type: String,
required: true
},
uid: {
type: Number,
required: true
},
},

data: function() {
return {
tab: 'repos',
repos: [],
reposTotal: 0,
reposFilter: 'all',
searchQuery: '',
isLoading: false
}
},

mounted: function() {
this.searchRepos();

var self = this;
Vue.nextTick(function() {
document.querySelector('#search_repo').focus();
self.$refs.search.focus();
});
},

Expand All @@ -1686,19 +1702,45 @@ function initDashboardSearch() {
this.tab = t;
},

searchKeyUp: function() {
this.searchRepos();
changeReposFilter: function(filter) {
this.reposFilter = filter;
},

showRepo: function(repo, filter) {
switch (filter) {
case 'sources':
return repo.owner.id == this.uid && !repo.mirror && !repo.fork;
case 'forks':
return repo.owner.id == this.uid && !repo.mirror && repo.fork;
case 'mirrors':
return repo.mirror;
case 'collaborative':
return repo.owner.id != this.uid;
default:
return true;
}
},

searchRepos: function() {
var self = this;
$.getJSON(this.searchURL(), function(result) {
self.repos = result.data;
this.isLoading = true;
var searchedQuery = this.searchQuery;
$.getJSON(this.searchURL(), function(result, textStatus, request) {
if (searchedQuery == self.searchQuery) {
self.repos = result.data;
if (searchedQuery == "") {
self.reposTotal = request.getResponseHeader('X-Total-Count');
}
}
}).always(function() {
if (searchedQuery == self.searchQuery) {
self.isLoading = false;
}
});
},

searchURL: function() {
return this.suburl + '/api/v1/repos/search?uid=' + this.uid + '&q=' + this.searchQuery;
return this.suburl + '/api/v1/repos/search?uid=' + this.uid + '&q=' + this.searchQuery + '&limit=' + this.searchLimit;
},

repoClass: function(repo) {
Expand All @@ -1713,5 +1755,25 @@ function initDashboardSearch() {
}
}
}
})
}

function initDashboardSearch() {
var el = document.getElementById('dashboard-repo-search');
if (!el) {
return;
}

initVueComponents();

new Vue({
delimiters: ['${', '}'],
el: el,

data: {
searchLimit: document.querySelector('meta[name=_search_limit]').content,
suburl: document.querySelector('meta[name=_suburl]').content,
uid: document.querySelector('meta[name=_context_uid]').content,
},
});
}
14 changes: 14 additions & 0 deletions public/less/_base.less
Original file line number Diff line number Diff line change
Expand Up @@ -464,3 +464,17 @@ footer {
padding-right: 30px !important;
}
}

[v-cloak] {
display: none !important;
}

.repos-search {
padding-bottom: 0 !important;
}

.repos-filter {
margin-top: 0 !important;
border-bottom-width: 0 !important;
margin-bottom: 2px !important;
}
2 changes: 2 additions & 0 deletions routers/api/v1/repo/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package repo

import (
"fmt"
"strings"

api "code.gitea.io/sdk/gitea"
Expand Down Expand Up @@ -91,6 +92,7 @@ func Search(ctx *context.APIContext) {
}

ctx.SetLinkHeader(int(count), setting.API.MaxResponseItems)
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", count))
ctx.JSON(200, api.SearchResults{
OK: true,
Data: results,
Expand Down
1 change: 1 addition & 0 deletions routers/user/home.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ func Dashboard(ctx *context.Context) {
ctx.Data["Title"] = ctxUser.DisplayName() + " - " + ctx.Tr("dashboard")
ctx.Data["PageIsDashboard"] = true
ctx.Data["PageIsNews"] = true
ctx.Data["SearchLimit"] = setting.UI.User.RepoPagingNum

// Only user can have collaborative repositories.
if !ctxUser.IsOrganization() {
Expand Down
8 changes: 4 additions & 4 deletions templates/base/footer.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,6 @@
<script src="{{AppSubUrl}}/js/draw.js"></script>
{{end}}

<!-- JavaScript -->
<script src="{{AppSubUrl}}/js/semantic-2.2.1.min.js"></script>
<script src="{{AppSubUrl}}/js/index.js?v={{MD5 AppVer}}"></script>

<!-- Third-party libraries -->
{{if .RequireHighlightJS}}
<script src="{{AppSubUrl}}/plugins/highlight-9.11.0/highlight.pack.js"></script>
Expand All @@ -66,5 +62,9 @@
<script src="{{AppSubUrl}}/js/libs/emojify-1.1.0.min.js"></script>
<script src="{{AppSubUrl}}/js/libs/clipboard-1.5.9.min.js"></script>
<script src="{{AppSubUrl}}/js/libs/vue.min.js"></script>

<!-- JavaScript -->
<script src="{{AppSubUrl}}/js/semantic-2.2.1.min.js"></script>
<script src="{{AppSubUrl}}/js/index.js?v={{MD5 AppVer}}"></script>
</body>
</html>
3 changes: 3 additions & 0 deletions templates/base/head.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
{{if .ContextUser}}
<meta name="_context_uid" content="{{.ContextUser.ID}}" />
{{end}}
{{if .SearchLimit}}
<meta name="_search_limit" content="{{.SearchLimit}}" />
{{end}}
{{if .GoGetImport}}
<meta name="go-import" content="{{.GoGetImport}} git {{.CloneLink.HTTPS}}">
<meta name="go-source" content="{{.GoGetImport}} _ {{.GoDocDirectory}} {{.GoDocFile}}">
Expand Down
99 changes: 2 additions & 97 deletions templates/user/dashboard/dashboard.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -8,105 +8,10 @@
{{template "user/dashboard/feeds" .}}
</div>
<div id="dashboard-repo-search" class="six wide column">
<div class="ui {{if not .ContextUser.IsOrganization}}three{{else}}two{{end}} item stackable tabable menu">
<a :class="{item: true, active: tab === 'repos'}" @click="changeTab('repos')">{{.i18n.Tr "repository"}}</a>
{{if not .ContextUser.IsOrganization}}
<a :class="{item: true, active: tab === 'orgs'}" @click="changeTab('orgs')">{{.i18n.Tr "organization"}}</a>
{{end}}
<a :class="{item: true, active: tab === 'mirrors'}" @click="changeTab('mirrors')">{{.i18n.Tr "mirror"}}</a>
</div>
<div v-if="tab === 'repos'" class="ui tab active list">
<div class="ui fluid input">
<input @keyUp="searchKeyUp" v-model="searchQuery" id="search_repo" placeholder="{{.i18n.Tr "home.search_repos"}}">
</div>
<h4 class="ui top attached header">
{{.i18n.Tr "home.my_repos"}} <span class="ui grey label">{{.ContextUser.NumRepos}}</span>
<div class="ui right">
<a class="poping up" href="{{AppSubUrl}}/repo/create" data-content="{{.i18n.Tr "new_repo"}}" data-variation="tiny inverted" data-position="left center">
<i class="plus icon"></i>
<span class="sr-only">{{.i18n.Tr "new_repo"}}</span>
</a>
</div>
</h4>
<div class="ui attached table segment">
<ul class="repo-owner-name-list">
<li v-for="repo in repos" :class="{'private': repo.private}">
<a :href="'{{AppSubUrl}}/' + repo.full_name">
<i :class="repoClass(repo)"></i>
<strong class="text truncate item-name">${ repo.full_name }</strong>
<span class="ui right text light grey">
${ repo.stars_count } <i class="octicon octicon-star rear"></i>
</span>
</a>
</li>
{{if gt .ContextUser.NumRepos .MaxShowRepoNum}}
<li>
<a href="{{.ContextUser.HomeLink}}">{{.i18n.Tr "home.show_more_repos"}}</a>
</li>
{{end}}
</ul>
</div>
</div>

{{if not .ContextUser.IsOrganization}}
<div v-if="tab === 'orgs'" class="ui tab active list">
<h4 class="ui top attached header">
{{.i18n.Tr "home.my_orgs"}} <span class="ui grey label">{{.ContextUser.GetOrganizationCount}}</span>
<div class="ui right">
{{if .SignedUser.CanCreateOrganization}}
<a class="poping up" href="{{AppSubUrl}}/org/create" data-content="{{.i18n.Tr "new_org"}}" data-variation="tiny inverted" data-position="left center">
<i class="plus icon"></i>
<span class="sr-only">{{.i18n.Tr "new_org"}}</span>
</a>
{{end}}
</div>
</h4>
<div class="ui attached table segment">
<ul class="repo-owner-name-list">
{{range .ContextUser.Orgs}}
<li>
<a href="{{AppSubUrl}}/{{.Name}}">
<i class="octicon octicon-organization"></i>
<strong class="text truncate item-name">{{.Name}}</strong>
<span class="ui right text light grey">
{{.NumRepos}} <i class="octicon octicon-repo rear"></i>
</span>
</a>
</li>
{{end}}
</ul>
</div>
</div>
{{end}}

<div v-if="tab === 'mirrors'" class="ui tab active list">
<h4 class="ui top attached header">
{{.i18n.Tr "home.my_mirrors"}} <span class="ui grey label">{{.MirrorCount}}</span>
<div class="ui right">
<a class="poping up" href="{{AppSubUrl}}/repo/migrate?mirror=1" data-content="{{.i18n.Tr "new_mirror"}}" data-variation="tiny inverted" data-position="left center">
<i class="plus icon"></i>
<span class="sr-only">{{.i18n.Tr "new_mirror"}}</span>
</a>
</div>
</h4>
<div class="ui attached table segment">
<ul class="repo-owner-name-list">
{{range .Mirrors}}
<li {{if .IsPrivate}}class="private"{{end}}>
<a href="{{AppSubUrl}}/{{$.ContextUser.Name}}/{{.Name}}">
<i class="octicon octicon-repo-clone"></i>
<strong class="text truncate item-name">{{.Name}}</strong>
<span class="ui right text light grey">
{{.Interval}}H <i class="octicon octicon-sync rear"></i>
</span>
</a>
</li>
{{end}}
</ul>
</div>
</div>
<repo-search :search-limit="searchLimit" :suburl="suburl" :uid="uid"><i class="fa fa-spinner fa-spin"></i></repo-search>
</div>
</div>
</div>
</div>
{{template "user/dashboard/repo-search" .}}
{{template "base/footer" .}}
Loading