Skip to content

Commit 0d24c06

Browse files
6543silverwind
authored and
Yohann Delafollye
committed
[UI] Sortable Tables Header By Click (go-gitea#7980)
* [UI] Sortable Tables Header By Click * get rid of padding above header * restart CI * fix lint * convert getArrow JS to SortArrow go func * addopt SortArrow funct * suggestions from @silverwind - tablesort.js Co-authored-by: silverwind <[email protected]> * Update web_src/js/features/tablesort.js Co-authored-by: silverwind <[email protected]> * Update web_src/js/features/tablesort.js Co-authored-by: silverwind <[email protected]> Co-authored-by: silverwind <[email protected]>
1 parent bebbf01 commit 0d24c06

File tree

10 files changed

+106
-18
lines changed

10 files changed

+106
-18
lines changed

modules/templates/helper.go

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,8 +298,30 @@ func NewFuncMap() []template.FuncMap {
298298
}
299299
return false
300300
},
301-
"svg": func(icon string, size int) template.HTML {
302-
return template.HTML(fmt.Sprintf(`<svg class="svg %s" width="%d" height="%d" aria-hidden="true"><use xlink:href="#%s" /></svg>`, icon, size, size, icon))
301+
"svg": SVG,
302+
"SortArrow": func(normSort, revSort, urlSort string, isDefault bool) template.HTML {
303+
// if needed
304+
if len(normSort) == 0 || len(urlSort) == 0 {
305+
return ""
306+
}
307+
308+
if len(urlSort) == 0 && isDefault {
309+
// if sort is sorted as default add arrow tho this table header
310+
if isDefault {
311+
return SVG("octicon-triangle-down", 16)
312+
}
313+
} else {
314+
// if sort arg is in url test if it correlates with column header sort arguments
315+
if urlSort == normSort {
316+
// the table is sorted with this header normal
317+
return SVG("octicon-triangle-down", 16)
318+
} else if urlSort == revSort {
319+
// the table is sorted with this header reverse
320+
return SVG("octicon-triangle-up", 16)
321+
}
322+
}
323+
// the table is NOT sorted with this header
324+
return ""
303325
},
304326
}}
305327
}
@@ -410,6 +432,11 @@ func NewTextFuncMap() []texttmpl.FuncMap {
410432
}}
411433
}
412434

435+
// SVG render icons
436+
func SVG(icon string, size int) template.HTML {
437+
return template.HTML(fmt.Sprintf(`<svg class="svg %s" width="%d" height="%d" aria-hidden="true"><use xlink:href="#%s" /></svg>`, icon, size, size, icon))
438+
}
439+
413440
// Safe render raw as HTML
414441
func Safe(raw string) template.HTML {
415442
return template.HTML(raw)

templates/admin/emails/list.tmpl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,15 @@
3333
<table class="ui very basic striped table">
3434
<thead>
3535
<tr>
36-
<th>{{.i18n.Tr "admin.users.name"}}</th>
36+
<th data-sortt-asc="username" data-sortt-desc="reverseusername">
37+
{{.i18n.Tr "admin.users.name"}}
38+
{{SortArrow "username" "reverseusername" $.SortType false}}
39+
</th>
3740
<th>{{.i18n.Tr "admin.users.full_name"}}</th>
38-
<th>{{.i18n.Tr "email"}}</th>
41+
<th data-sortt-asc="email" data-sortt-desc="reverseemail" data-sortt-default="true">
42+
{{.i18n.Tr "email"}}
43+
{{SortArrow "email" "reverseemail" $.SortType true}}
44+
</th>
3945
<th>{{.i18n.Tr "admin.emails.primary"}}</th>
4046
<th>{{.i18n.Tr "admin.emails.activated"}}</th>
4147
</tr>

templates/admin/org/list.tmpl

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,18 @@
1616
<table class="ui very basic striped table">
1717
<thead>
1818
<tr>
19-
<th>ID</th>
20-
<th>{{.i18n.Tr "admin.orgs.name"}}</th>
19+
<th data-sortt-asc="oldest" data-sortt-desc="newest">ID{{SortArrow "oldest" "newest" $.SortType false}}</th>
20+
<th data-sortt-asc="alphabetically" data-sortt-desc="reversealphabetically" data-sortt-default="true">
21+
{{.i18n.Tr "admin.orgs.name"}}
22+
{{SortArrow "alphabetically" "reversealphabetically" $.SortType true}}
23+
</th>
2124
<th>{{.i18n.Tr "admin.orgs.teams"}}</th>
2225
<th>{{.i18n.Tr "admin.orgs.members"}}</th>
2326
<th>{{.i18n.Tr "admin.users.repos"}}</th>
24-
<th>{{.i18n.Tr "admin.users.created"}}</th>
27+
<th data-sortt-asc="recentupdate" data-sortt-desc="leastupdate">
28+
{{.i18n.Tr "admin.users.created"}}
29+
{{SortArrow "recentupdate" "leastupdate" $.SortType false}}
30+
</th>
2531
<th>{{.i18n.Tr "admin.users.edit"}}</th>
2632
</tr>
2733
</thead>

templates/admin/repo/list.tmpl

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,27 @@
1313
<table class="ui very basic striped table">
1414
<thead>
1515
<tr>
16-
<th>ID</th>
16+
<th data-sortt-asc="oldest" data-sortt-desc="newest">ID{{SortArrow "oldest" "newest" $.SortType false}}</th>
1717
<th>{{.i18n.Tr "admin.repos.owner"}}</th>
18-
<th>{{.i18n.Tr "admin.repos.name"}}</th>
18+
<th data-sortt-asc="alphabetically" data-sortt-desc="reversealphabetically">
19+
{{.i18n.Tr "admin.repos.name"}}
20+
{{SortArrow "alphabetically" "reversealphabetically" $.SortType false}}
21+
</th>
1922
<th>{{.i18n.Tr "admin.repos.private"}}</th>
2023
<th>{{.i18n.Tr "admin.repos.watches"}}</th>
21-
<th>{{.i18n.Tr "admin.repos.stars"}}</th>
22-
<th>{{.i18n.Tr "admin.repos.forks"}}</th>
24+
<th data-sortt-asc="moststars" data-sortt-desc="feweststars">
25+
{{.i18n.Tr "admin.repos.stars"}}
26+
{{SortArrow "moststars" "feweststars" $.SortType false}}
27+
</th>
28+
<th data-sortt-asc="mostforks" data-sortt-desc="fewestforks">
29+
{{.i18n.Tr "admin.repos.forks"}}
30+
{{SortArrow "mostforks" "fewestforks" $.SortType false}}
31+
</th>
2332
<th>{{.i18n.Tr "admin.repos.issues"}}</th>
24-
<th>{{.i18n.Tr "admin.repos.size"}}</th>
33+
<th data-sortt-asc="size" data-sortt-desc="reversesize">
34+
{{.i18n.Tr "admin.repos.size"}}
35+
{{SortArrow "size" "reversesize" $.SortType false}}
36+
</th>
2537
<th>{{.i18n.Tr "admin.users.created"}}</th>
2638
<th>{{.i18n.Tr "admin.notices.op"}}</th>
2739
</tr>

templates/admin/user/list.tmpl

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,21 @@
1616
<table class="ui very basic striped table">
1717
<thead>
1818
<tr>
19-
<th>ID</th>
20-
<th>{{.i18n.Tr "admin.users.name"}}</th>
19+
<th data-sortt-asc="oldest" data-sortt-desc="newest">ID{{SortArrow "oldest" "newest" .SortType false}}</th>
20+
<th data-sortt-asc="alphabetically" data-sortt-desc="reversealphabetically" data-sortt-default="true">
21+
{{.i18n.Tr "admin.users.name"}}
22+
{{SortArrow "alphabetically" "reversealphabetically" $.SortType true}}
23+
</th>
2124
<th>{{.i18n.Tr "email"}}</th>
2225
<th>{{.i18n.Tr "admin.users.activated"}}</th>
2326
<th>{{.i18n.Tr "admin.users.admin"}}</th>
2427
<th>{{.i18n.Tr "admin.users.restricted"}}</th>
2528
<th>{{.i18n.Tr "admin.users.repos"}}</th>
2629
<th>{{.i18n.Tr "admin.users.created"}}</th>
27-
<th>{{.i18n.Tr "admin.users.last_login"}}</th>
30+
<th data-sortt-asc="recentupdate" data-sortt-desc="leastupdate">
31+
{{.i18n.Tr "admin.users.last_login"}}
32+
{{SortArrow "recentupdate" "leastupdate" $.SortType false}}
33+
</th>
2834
<th>{{.i18n.Tr "admin.users.edit"}}</th>
2935
</tr>
3036
</thead>

web_src/js/features/tablesort.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
export default function initTableSort() {
2+
for (const header of document.querySelectorAll('th[data-sortt-asc]') || []) {
3+
const {sorttAsc, sorttDesc, sorttDefault} = header.dataset;
4+
header.addEventListener('click', () => {
5+
tableSort(sorttAsc, sorttDesc, sorttDefault);
6+
});
7+
}
8+
}
9+
10+
function tableSort(normSort, revSort, isDefault) {
11+
if (!normSort) return false;
12+
if (!revSort) revSort = '';
13+
14+
const url = new URL(window.location);
15+
let urlSort = url.searchParams.get('sort');
16+
if (!urlSort && isDefault) urlSort = normSort;
17+
18+
url.searchParams.set('sort', urlSort !== normSort ? normSort : revSort);
19+
window.location.replace(url.href);
20+
}

web_src/js/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import initUserHeatmap from './features/userheatmap.js';
1515
import initServiceWorker from './features/serviceworker.js';
1616
import attachTribute from './features/tribute.js';
1717
import createDropzone from './features/dropzone.js';
18+
import initTableSort from './features/tablesort.js';
1819
import highlight from './features/highlight.js';
1920
import ActivityTopAuthors from './components/ActivityTopAuthors.vue';
2021
import {initNotificationsTable, initNotificationCount} from './features/notification.js';
@@ -2450,6 +2451,7 @@ $(document).ready(async () => {
24502451
initRepoStatusChecker();
24512452
initTemplateSearch();
24522453
initContextPopups();
2454+
initTableSort();
24532455
initNotificationsTable();
24542456
initNotificationCount();
24552457

web_src/less/_admin.less

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
font-size: 13px;
77

88
&:not(.striped) {
9-
padding-top: 5px;
10-
119
thead {
1210
th:last-child {
1311
padding-right: 5px !important;

web_src/less/_base.less

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,6 +1223,17 @@ i.icon.centerlock {
12231223
margin-top: 1rem;
12241224
}
12251225

1226+
table th[data-sortt-asc],
1227+
table th[data-sortt-desc] {
1228+
&:hover {
1229+
background: rgba(0, 0, 0, .1) !important;
1230+
cursor: pointer !important;
1231+
}
1232+
.svg {
1233+
margin-left: .25rem;
1234+
}
1235+
}
1236+
12261237
/* limit width of all direct dropdown menu children */
12271238
/* https://github.com/go-gitea/gitea/pull/10835 */
12281239
.dropdown:not(.selection) > .menu:not(.review-box) > *:not(.header) {

web_src/less/themes/theme-arc-green.less

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ a.ui.basic.green.label:hover {
479479

480480
.ui.table thead th,
481481
.ui.table > thead > tr > th {
482-
background: #404552 !important;
482+
background: #404552;
483483
color: #dbdbdb !important;
484484
}
485485

0 commit comments

Comments
 (0)