Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Add icons on sortable table headers to show which columns are sortable and which is the current sort column. This code is inspired by the brlist-visual-enhancement branch, but is a completely new implementation. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
8533365e44fab97b6e2375eb42d9ca22 |
| User & Date: | drh 2015-01-06 01:06:55.570 |
Context
|
2015-01-06
| ||
| 13:14 | Add the --verbose option to the clone command. ... (check-in: 5e7d3effa3 user: drh tags: trunk) | |
| 06:46 | Extend verbose option to clone operations as well. ... (Closed-Leaf check-in: 7421f9263c user: andybradford tags: pending-review) | |
| 01:06 | Add icons on sortable table headers to show which columns are sortable and which is the current sort column. This code is inspired by the brlist-visual-enhancement branch, but is a completely new implementation. ... (check-in: 8533365e44 user: drh tags: trunk) | |
|
2015-01-05
| ||
| 22:39 | Fix typo in a new #define. ... (check-in: c761af63c0 user: mistachkin tags: trunk) | |
Changes
Changes to src/branch.c.
| ︙ | ︙ | |||
322 323 324 325 326 327 328 | @ (SELECT uuid FROM blob WHERE rid=tagxref.rid) @ FROM tagxref, tag, event @ WHERE tagxref.tagid=tag.tagid @ AND tagxref.tagtype>0 @ AND tag.tagname='branch' @ AND event.objid=tagxref.rid @ GROUP BY 1 | | < < | | 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 |
@ (SELECT uuid FROM blob WHERE rid=tagxref.rid)
@ FROM tagxref, tag, event
@ WHERE tagxref.tagid=tag.tagid
@ AND tagxref.tagtype>0
@ AND tag.tagname='branch'
@ AND event.objid=tagxref.rid
@ GROUP BY 1
@ ORDER BY 2 DESC;
;
/*
** This is the new-style branch-list page that shows the branch names
** together with their ages (time of last check-in) and whether or not
** they are closed or merged to another branch.
**
** Control jumps to this routine from brlist_page() (the /brlist handler)
** if there are no query parameters.
*/
static void new_brlist_page(void){
Stmt q;
double rNow;
login_check_credentials();
if( !g.perm.Read ){ login_needed(); return; }
style_header("Branches");
login_anonymous_available();
db_prepare(&q, brlistQuery/*works-like:""*/);
rNow = db_double(0.0, "SELECT julianday('now')");
@ <div class="brlist"><table id="branchlisttable">
@ <thead><tr>
@ <th>Branch Name</th>
@ <th>Age</th>
@ <th>Checkins</th>
@ <th>Status</th>
|
| ︙ | ︙ | |||
379 380 381 382 383 384 385 |
}else{
@ <td></td>
}
@ </tr>
}
@ </tbody></table></div>
db_finalize(&q);
| | | 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 |
}else{
@ <td></td>
}
@ </tr>
}
@ </tbody></table></div>
db_finalize(&q);
output_table_sorting_javascript("branchlisttable","tkktx",2);
style_footer();
}
/*
** WEBPAGE: brlist
** Show a list of branches
** Query parameters:
|
| ︙ | ︙ |
Changes to src/report.c.
| ︙ | ︙ | |||
920 921 922 923 924 925 926 | return rc; } /* ** Output Javascript code that will enables sorting of the table with ** the id zTableId by clicking. ** | | > > > > > > > | > > > > | > | > | > > > > > > > > > > > > > > > > > > > | 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 |
return rc;
}
/*
** Output Javascript code that will enables sorting of the table with
** the id zTableId by clicking.
**
** The javascript was originally derived from:
**
** http://www.webtoolkit.info/sortable-html-table.html
**
** But there have been extensive modifications.
**
** This variation allows column types to be expressed using the second
** argument. Each character of the second argument represent a column.
**
** t Sort by text
** n Sort numerically
** k Sort by the data-sortkey property
** x This column is not sortable
**
** If there are fewer characters in zColumnTypes[] than their are columns,
** the all extra columns assume type "t" (text).
**
** The third parameter is the column that was initially sorted (using 1-based
** column numbers, like SQL). Make this value 0 if none of the columns are
** initially sorted. Make the value negative if the column is initially sorted
** in reverse order.
**
** Clicking on the same column header twice in a row inverts the sort.
*/
void output_table_sorting_javascript(
const char *zTableId, /* ID of table to sort */
const char *zColumnTypes, /* String for column types */
int iInitSort /* Initially sorted column. Leftmost is 1. 0 for NONE */
){
@ <script>
@ function SortableTable(tableEl,columnTypes,initSort){
@ this.tbody = tableEl.getElementsByTagName('tbody');
@ this.columnTypes = columnTypes;
@ this.sort = function (cell) {
@ var column = cell.cellIndex;
@ var sortFn;
@ switch( cell.sortType ){
@ case "n": sortFn = this.sortNumeric; break;
@ case "t": sortFn = this.sortText; break;
@ case "k": sortFn = this.sortKey; break;
@ case "x": return;
@ }
@ this.sortIndex = column;
@ var newRows = new Array();
@ for (j = 0; j < this.tbody[0].rows.length; j++) {
@ newRows[j] = this.tbody[0].rows[j];
@ }
@ if( this.sortIndex==Math.abs(this.prevColumn)-1 ){
@ newRows.reverse();
@ this.prevColumn = -this.prevColumn;
@ }else{
@ newRows.sort(sortFn);
@ this.prevColumn = this.sortIndex+1;
@ }
@ for (i=0;i<newRows.length;i++) {
@ this.tbody[0].appendChild(newRows[i]);
@ }
@ this.setHdrIcons();
@ }
@ this.setHdrIcons = function() {
@ var arrowdiv = this.hdrRow.getElementsByClassName("sortarrow");
@ while( arrowdiv[0] ){
@ arrowdiv[0].parentNode.removeChild(arrowdiv[0]);
@ }
@ for (var i=0; i<this.hdrRow.cells.length; i++) {
@ if( this.columnTypes[i]=='x' ) continue;
@ if( this.prevColumn==i+1 ){
@ arrow = "\u2b07";
@ }else if( this.prevColumn==(-1-i) ){
@ arrow = "\u2b06";
@ }else{
@ arrow = "\u21f3";
@ }
@ this.hdrRow.cells[i].innerHTML +=
@ "<span class='sortarrow'>" + arrow + "</div>";
@ }
@ }
@ this.sortText = function(a,b) {
@ var i = thisObject.sortIndex;
@ aa = a.cells[i].textContent.replace(/^\W+/,'').toLowerCase();
@ bb = b.cells[i].textContent.replace(/^\W+/,'').toLowerCase();
@ if(aa==bb) return 0;
@ if(aa<bb) return -1;
|
| ︙ | ︙ | |||
989 990 991 992 993 994 995 |
@ var i = thisObject.sortIndex;
@ aa = a.cells[i].getAttribute("data-sortkey");
@ bb = b.cells[i].getAttribute("data-sortkey");
@ if(aa==bb) return 0;
@ if(aa<bb) return -1;
@ return 1;
@ }
| < < | > > | > | | | | > | | 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 |
@ var i = thisObject.sortIndex;
@ aa = a.cells[i].getAttribute("data-sortkey");
@ bb = b.cells[i].getAttribute("data-sortkey");
@ if(aa==bb) return 0;
@ if(aa<bb) return -1;
@ return 1;
@ }
@ var x = tableEl.getElementsByTagName('thead');
@ if(!(this.tbody && this.tbody[0].rows && this.tbody[0].rows.length>0)){
@ return;
@ }
@ if(x && x[0].rows && x[0].rows.length > 0) {
@ this.hdrRow = x[0].rows[0];
@ } else {
@ return;
@ }
@ var thisObject = this;
@ this.prevColumn = initSort;
@ for (var i=0; i<this.hdrRow.cells.length; i++) {
@ if( columnTypes[i]=='x' ) continue;
@ var hdrcell = this.hdrRow.cells[i];
@ hdrcell.sTable = this;
@ hdrcell.style.cursor = "pointer";
@ hdrcell.sortType = columnTypes[i] || 't';
@ hdrcell.onclick = function () {
@ this.sTable.sort(this);
@ return false;
@ }
@ }
@ this.setHdrIcons()
@ }
@ var t = new SortableTable(gebi("%s(zTableId)"),"%s(zColumnTypes)",%d(iInitSort));
@ </script>
}
/*
** WEBPAGE: /rptview
**
|
| ︙ | ︙ | |||
1107 1108 1109 1110 1111 1112 1113 |
report_unrestrict_sql();
@ </tbody></table>
if( zErr1 ){
@ <p class="reportError">Error: %h(zErr1)</p>
}else if( zErr2 ){
@ <p class="reportError">Error: %h(zErr2)</p>
}
| | | 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 |
report_unrestrict_sql();
@ </tbody></table>
if( zErr1 ){
@ <p class="reportError">Error: %h(zErr1)</p>
}else if( zErr2 ){
@ <p class="reportError">Error: %h(zErr2)</p>
}
output_table_sorting_javascript("reportTable","",0);
style_footer();
}else{
report_restrict_sql(&zErr1);
db_exec_readonly(g.db, zSql, output_tab_separated, &count, &zErr2);
report_unrestrict_sql();
cgi_set_content_type("text/plain");
}
|
| ︙ | ︙ |
Changes to src/timeline.c.
| ︙ | ︙ | |||
2397 2398 2399 2400 2401 2402 2403 |
const char *zAvgLabel = includeMonth ? "month" : "year";
int nAvg = iterations ? (nEventTotal/iterations) : 0;
@ <br><div>Total events: %d(nEventTotal)
@ <br>Average per active %s(zAvgLabel): %d(nAvg)
@ </div>
}
if( !includeMonth ){
| | | 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 |
const char *zAvgLabel = includeMonth ? "month" : "year";
int nAvg = iterations ? (nEventTotal/iterations) : 0;
@ <br><div>Total events: %d(nEventTotal)
@ <br>Average per active %s(zAvgLabel): %d(nAvg)
@ </div>
}
if( !includeMonth ){
output_table_sorting_javascript("statsTable","tnx",-1);
}
}
/*
** Implements the "byuser" view for /reports.
*/
static void stats_report_by_user(){
|
| ︙ | ︙ | |||
2448 2449 2450 2451 2452 2453 2454 |
if(!nCount) continue /* arguable! Possible? */;
else if(!nSize) nSize = 1;
rowClass = ++nRowNumber % 2;
nEventTotal += nCount;
@<tr class='row%d(rowClass)'>
@ <td>
@ <a href="?view=bymonth&user=%h(zUser)&type=%c((char)statsReportType)">%h(zUser)</a>
| | | | 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 |
if(!nCount) continue /* arguable! Possible? */;
else if(!nSize) nSize = 1;
rowClass = ++nRowNumber % 2;
nEventTotal += nCount;
@<tr class='row%d(rowClass)'>
@ <td>
@ <a href="?view=bymonth&user=%h(zUser)&type=%c((char)statsReportType)">%h(zUser)</a>
@ </td><td data-sortkey='%08x(-nCount)'>%d(nCount)</td>
@ <td>
@ <div class='statistics-report-graph-line'
@ style='width:%d(nSize)%%;'> </div>
@ </td>
@</tr>
/*
Potential improvement: calculate the min/max event counts and
use percent-based graph bars.
*/
}
@ </tbody></table>
db_finalize(&query);
output_table_sorting_javascript("statsTable","tkx",2);
}
/*
** Implements the "byweekday" view for /reports.
*/
static void stats_report_day_of_week(){
Stmt query = empty_Stmt;
|
| ︙ | ︙ | |||
2526 2527 2528 2529 2530 2531 2532 |
@ <div class='statistics-report-graph-line'
@ style='width:%d(nSize)%%;'> </div>
@ </td>
@</tr>
}
@ </tbody></table>
db_finalize(&query);
| | | 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 |
@ <div class='statistics-report-graph-line'
@ style='width:%d(nSize)%%;'> </div>
@ </td>
@</tr>
}
@ </tbody></table>
db_finalize(&query);
output_table_sorting_javascript("statsTable","ntnx",1);
}
/*
** Helper for stats_report_by_month_year(), which generates a list of
** week numbers. zTimeframe should be either a timeframe in the form YYYY
** or YYYY-MM.
|
| ︙ | ︙ | |||
2659 2660 2661 2662 2663 2664 2665 |
cgi_printf("</tbody></table>");
if(total){
int nAvg = iterations ? (total/iterations) : 0;
cgi_printf("<br><div>Total events: %d<br>"
"Average per active week: %d</div>",
total, nAvg);
}
| | | 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 |
cgi_printf("</tbody></table>");
if(total){
int nAvg = iterations ? (total/iterations) : 0;
cgi_printf("<br><div>Total events: %d<br>"
"Average per active week: %d</div>",
total, nAvg);
}
output_table_sorting_javascript("statsTable","tnx",-1);
}
}
/*
** WEBPAGE: reports
**
** Shows activity reports for the repository.
|
| ︙ | ︙ |