mirror of
https://github.com/ohwgiles/laminar.git
synced 2024-10-27 20:34:20 +00:00
show active jobs on Jobs page
Rows on the jobs page now updated also during their execution. This improvement was discussed in #8 and #9
This commit is contained in:
parent
022aa0d804
commit
d3e4db1f29
@ -246,11 +246,14 @@ void Laminar::sendStatus(LaminarClient* client) {
|
|||||||
|
|
||||||
} else if(client->scope.type == MonitorScope::ALL) {
|
} else if(client->scope.type == MonitorScope::ALL) {
|
||||||
j.startArray("jobs");
|
j.startArray("jobs");
|
||||||
db->stmt("SELECT name,number,startedAt,result FROM builds GROUP BY name ORDER BY number DESC")
|
db->stmt("SELECT name,number,startedAt,completedAt,result FROM builds GROUP BY name ORDER BY number DESC")
|
||||||
.fetch<str,int,time_t,int>([&](str name,int number, time_t started, int result){
|
.fetch<str,int,time_t,time_t,int>([&](str name,int number, time_t started, time_t completed, int result){
|
||||||
j.StartObject();
|
j.StartObject();
|
||||||
j.set("name", name);
|
j.set("name", name);
|
||||||
j.set("number", number).set("result", to_string(RunState(result))).set("started", started);
|
j.set("number", number);
|
||||||
|
j.set("result", to_string(RunState(result)));
|
||||||
|
j.set("started", started);
|
||||||
|
j.set("completed", completed);
|
||||||
j.startArray("tags");
|
j.startArray("tags");
|
||||||
for(const str& t: jobTags[name]) {
|
for(const str& t: jobTags[name]) {
|
||||||
j.String(t.c_str());
|
j.String(t.c_str());
|
||||||
@ -259,6 +262,21 @@ void Laminar::sendStatus(LaminarClient* client) {
|
|||||||
j.EndObject();
|
j.EndObject();
|
||||||
});
|
});
|
||||||
j.EndArray();
|
j.EndArray();
|
||||||
|
j.startArray("running");
|
||||||
|
for(const std::shared_ptr<Run> run : activeJobs.get<3>()) {
|
||||||
|
j.StartObject();
|
||||||
|
j.set("name", run->name);
|
||||||
|
j.set("number", run->build);
|
||||||
|
j.set("node", run->node->name);
|
||||||
|
j.set("started", run->startedAt);
|
||||||
|
j.startArray("tags");
|
||||||
|
for(const str& t: jobTags[run->name]) {
|
||||||
|
j.String(t.c_str());
|
||||||
|
}
|
||||||
|
j.EndArray();
|
||||||
|
j.EndObject();
|
||||||
|
}
|
||||||
|
j.EndArray();
|
||||||
} else { // Home page
|
} else { // Home page
|
||||||
j.startArray("recent");
|
j.startArray("recent");
|
||||||
db->stmt("SELECT * FROM builds ORDER BY completedAt DESC LIMIT 15")
|
db->stmt("SELECT * FROM builds ORDER BY completedAt DESC LIMIT 15")
|
||||||
|
@ -113,6 +113,7 @@
|
|||||||
<td><router-link :to="'/jobs/'+job.name">{{job.name}}</router-link></td>
|
<td><router-link :to="'/jobs/'+job.name">{{job.name}}</router-link></td>
|
||||||
<td class="text-center"><span v-html="runIcon(job.result)"></span> <router-link :to="'/jobs/'+job.name+'/'+job.number">#{{job.number}}</router-link></td>
|
<td class="text-center"><span v-html="runIcon(job.result)"></span> <router-link :to="'/jobs/'+job.name+'/'+job.number">#{{job.number}}</router-link></td>
|
||||||
<td class="text-center">{{formatDate(job.started)}}</td>
|
<td class="text-center">{{formatDate(job.started)}}</td>
|
||||||
|
<td class="text-center">{{formatDuration(job.started,job.completed)}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -54,7 +54,7 @@ const WebsocketHandler = function() {
|
|||||||
const Utils = {
|
const Utils = {
|
||||||
methods: {
|
methods: {
|
||||||
runIcon(result) {
|
runIcon(result) {
|
||||||
return result === "success" ? '<span style="color:forestgreen;font-family:\'Zapf Dingbats\';">✔</span>' : result === "failed" || result === "aborted" ? '<span style="color:crimson;">✘</span>' : '';
|
return result === "success" ? '<span style="color:forestgreen;font-family:\'Zapf Dingbats\';">✔</span>' : result === "failed" || result === "aborted" ? '<span style="color:crimson;">✘</span>' : '<img class="spin small" src="/progress.gif">';
|
||||||
},
|
},
|
||||||
formatDate: function(unix) {
|
formatDate: function(unix) {
|
||||||
// TODO: reimplement when toLocaleDateString() accepts formatting options on most browsers
|
// TODO: reimplement when toLocaleDateString() accepts formatting options on most browsers
|
||||||
@ -257,7 +257,7 @@ const Jobs = function() {
|
|||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
template: '#jobs',
|
template: '#jobs',
|
||||||
mixins: [WebsocketHandler, Utils],
|
mixins: [WebsocketHandler, Utils, ProgressUpdater],
|
||||||
data: function() { return state; },
|
data: function() { return state; },
|
||||||
computed: {
|
computed: {
|
||||||
filteredJobs() {
|
filteredJobs() {
|
||||||
@ -280,6 +280,13 @@ const Jobs = function() {
|
|||||||
methods: {
|
methods: {
|
||||||
status: function(msg) {
|
status: function(msg) {
|
||||||
state.jobs = msg.jobs;
|
state.jobs = msg.jobs;
|
||||||
|
state.jobsRunning = msg.running;
|
||||||
|
// mix running and completed jobs
|
||||||
|
for (var i in msg.running) {
|
||||||
|
var idx = state.jobs.findIndex(job => job.name === msg.running[i].name);
|
||||||
|
if (idx > -1)
|
||||||
|
state.jobs[idx] = msg.running[i];
|
||||||
|
}
|
||||||
var tags = {};
|
var tags = {};
|
||||||
for (var i in state.jobs) {
|
for (var i in state.jobs) {
|
||||||
for (var j in state.jobs[i].tags) {
|
for (var j in state.jobs[i].tags) {
|
||||||
@ -288,10 +295,38 @@ const Jobs = function() {
|
|||||||
}
|
}
|
||||||
state.tags = Object.keys(tags);
|
state.tags = Object.keys(tags);
|
||||||
},
|
},
|
||||||
|
job_started: function(data) {
|
||||||
|
var updAt = null;
|
||||||
|
for (var i in state.jobsRunning) {
|
||||||
|
if (state.jobsRunning[i].name === data.name) {
|
||||||
|
updAt = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (updAt === null) {
|
||||||
|
state.jobsRunning.unshift(data);
|
||||||
|
} else {
|
||||||
|
state.jobsRunning[updAt] = data;
|
||||||
|
}
|
||||||
|
for (var i in state.jobs) {
|
||||||
|
if (state.jobs[i].name === data.name) {
|
||||||
|
state.jobs[i] = data;
|
||||||
|
this.$forceUpdate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
job_completed: function(data) {
|
job_completed: function(data) {
|
||||||
for (var i in state.jobs) {
|
for (var i in state.jobs) {
|
||||||
if (state.jobs[i].name === data.name) {
|
if (state.jobs[i].name === data.name) {
|
||||||
state.jobs[i] = data;
|
state.jobs[i] = data;
|
||||||
|
// forceUpdate in second loop
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var i in state.jobsRunning) {
|
||||||
|
if (state.jobsRunning[i].name === data.name) {
|
||||||
|
state.jobsRunning.splice(i, 1);
|
||||||
this.$forceUpdate();
|
this.$forceUpdate();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user