1
0
mirror of https://github.com/ohwgiles/laminar.git synced 2026-03-02 03:40:21 +00:00

resolves #40: implement frontend sorting

This feature allows runs to be sorted by result, number, start time
or duration, in ascending or descending order, on the Job page. Request
is processed server-side so that the correct page division can be done.
Currently running jobs are not sorted.
This commit is contained in:
Oliver Giles
2018-08-24 12:15:40 +03:00
parent a81492e5bc
commit 8bcce4d5cc
5 changed files with 93 additions and 18 deletions

View File

@@ -63,6 +63,35 @@
@keyframes spin {
to { transform: rotate(360deg); }
}
/* sort indicators */
a.sort {
position: relative;
margin-left: 7px;
}
a.sort:before, a.sort:after {
border: 4px solid transparent;
content: "";
position: absolute;
display: block;
height: 0;
width: 0;
right: 0;
top: 50%;
}
a.sort:before {
border-bottom-color: #ccc;
margin-top: -9px;
}
a.sort:after {
border-top-color: #ccc;
margin-top: 1px;
}
a.sort.dsc:after { border-top-color: #000; }
a.sort.asc:before { border-bottom-color: #000; }
a.sort:hover { text-decoration: none; cursor:pointer; }
a.sort:not(.asc):hover:before { border-bottom-color: #777; }
a.sort:not(.dsc):hover:after { border-top-color: #777; }
</style>
</head>
<body>
@@ -170,28 +199,36 @@
</div>
</div>
<div class="row"><div class="col-xs-12">
<table class="table table-striped"><thead>
<tr><th>Run</th><th class="text-center">Started</th><th class="text-center">Duration</th><th class="text-center hidden-xs">Reason</th></tr></thead>
<table class="table table-striped">
<thead><tr>
<th><a class="sort" :class="(sort.field=='result'?sort.order:'')" v-on:click="do_sort('result')">&nbsp;</a></th>
<th>Run <a class="sort" :class="(sort.field=='number'?sort.order:'')" v-on:click="do_sort('number')">&nbsp;</a></th>
<th class="text-center">Started <a class="sort" :class="(sort.field=='started'?sort.order:'')" v-on:click="do_sort('started')">&nbsp;</a></th>
<th class="text-center">Duration <a class="sort" :class="(sort.field=='duration'?sort.order:'')" v-on:click="do_sort('duration')">&nbsp;</a></th>
<th class="text-center hidden-xs">Reason <a class="sort" :class="(sort.field=='reason'?sort.order:'')" v-on:click="do_sort('reason')">&nbsp;</a></th>
</tr></thead>
<tr v-show="nQueued">
<td colspan="4"><i>{{nQueued}} run(s) queued</i></td>
<td colspan="5"><i>{{nQueued}} run(s) queued</i></td>
</tr>
<tr v-for="job in jobsRunning" track-by="$index">
<td><span v-html="runIcon(job.result)"></span> <router-link :to="'/jobs/'+$route.params.name+'/'+job.number">#{{job.number}}</router-link></td>
<td style="width:1px"><span v-html="runIcon(job.result)"></span></td>
<td><router-link :to="'/jobs/'+$route.params.name+'/'+job.number">#{{job.number}}</router-link></td>
<td class="text-center">{{formatDate(job.started)}}</td>
<td class="text-center">{{formatDuration(job.started, job.completed)}}</td>
<td class="text-center hidden-xs">{{job.reason}}</td>
</tr>
<tr v-for="job in jobsRecent" track-by="$index">
<td><span v-html="runIcon(job.result)"></span> <router-link :to="'/jobs/'+$route.params.name+'/'+job.number">#{{job.number}}</router-link></td>
<td style="width:1px"><span v-html="runIcon(job.result)"></span></td>
<td><router-link :to="'/jobs/'+$route.params.name+'/'+job.number">#{{job.number}}</router-link></td>
<td class="text-center">{{formatDate(job.started)}}</td>
<td class="text-center">{{formatDuration(job.started, job.completed)}}</td>
<td class="text-center hidden-xs">{{job.reason}}</td>
</tr>
</table>
<ul class="pagination pull-right">
<li><button class="btn btn-default" v-on:click="page_prev" :disabled="page==0">&laquo;</button></li>
<li>Page {{page+1}} of {{pages}}</li>
<li><button class="btn btn-default" v-on:click="page_next" :disabled="page==pages-1">&raquo;</button></li>
<li><button class="btn btn-default" v-on:click="page_prev" :disabled="sort.page==0">&laquo;</button></li>
<li>Page {{sort.page+1}} of {{pages}}</li>
<li><button class="btn btn-default" v-on:click="page_next" :disabled="sort.page==pages-1">&raquo;</button></li>
</ul>
</div></div>
</div>

View File

@@ -402,7 +402,7 @@ var Job = function() {
lastFailed: null,
nQueued: 0,
pages: 0,
page: 0
sort: {}
};
return Vue.extend({
template: '#job',
@@ -418,7 +418,7 @@ var Job = function() {
state.lastFailed = msg.lastFailed;
state.nQueued = msg.nQueued;
state.pages = msg.pages;
state.page = msg.page;
state.sort = msg.sort;
var chtBt = new Chart(document.getElementById("chartBt"), {
type: 'bar',
@@ -467,10 +467,21 @@ var Job = function() {
}
},
page_next: function() {
this.ws.send(JSON.stringify({page:++state.page}));
state.sort.page++;
this.ws.send(JSON.stringify(state.sort));
},
page_prev: function() {
this.ws.send(JSON.stringify({page:--state.page}));
state.sort.page--;
this.ws.send(JSON.stringify(state.sort));
},
do_sort: function(field) {
if(state.sort.field == field) {
state.sort.order = state.sort.order == 'asc' ? 'dsc' : 'asc';
} else {
state.sort.order = 'dsc';
state.sort.field = field;
}
this.ws.send(JSON.stringify(state.sort));
}
}
});