2018-12-09 13:21:20 +00:00
|
|
|
|
<template>
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<div v-if="run != null">
|
|
|
|
|
|
<div class="run">
|
|
|
|
|
|
<div :class="runResultClass(run)">
|
|
|
|
|
|
<div class="run-content">
|
|
|
|
|
|
<div class="item-content columns">
|
|
|
|
|
|
<div class="run-title column is-10">
|
|
|
|
|
|
<span class="run-name">{{run.name}}</span>
|
|
|
|
|
|
<span
|
|
|
|
|
|
class="tag"
|
|
|
|
|
|
:class="'is-'+runResultClass(run)"
|
|
|
|
|
|
>{{ runStatus(run) | capitalize }}</span>
|
|
|
|
|
|
<span v-if="stillRunning(run)" class="stillrunning tag">Still running</span>
|
|
|
|
|
|
<span v-if="!stillRunning(run)" class="stillrunning"></span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="run-actions column is-2 is-pulled-right">
|
2019-03-29 10:25:29 +00:00
|
|
|
|
<div
|
|
|
|
|
|
v-if="run.can_restart_from_scratch || run.can_restart_from_failed_tasks"
|
2019-05-08 15:12:56 +00:00
|
|
|
|
class="dropdown is-right"
|
2019-05-17 15:00:46 +00:00
|
|
|
|
v-click-outside="() => dropdownActive = false"
|
2019-05-08 15:12:56 +00:00
|
|
|
|
v-bind:class="{ 'is-active': dropdownActive }"
|
2019-03-29 10:25:29 +00:00
|
|
|
|
>
|
2018-12-09 13:21:20 +00:00
|
|
|
|
<div class="dropdown-trigger">
|
2019-05-08 15:12:56 +00:00
|
|
|
|
<button class="button" @click="toggleDropdown()">
|
2018-12-09 13:21:20 +00:00
|
|
|
|
<span>Restart</span>
|
|
|
|
|
|
<span class="icon is-small">
|
|
|
|
|
|
<i class="mdi mdi-restart" aria-hidden="true"></i>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="dropdown-menu" role="menu">
|
|
|
|
|
|
<div class="dropdown-content">
|
2019-03-29 10:25:29 +00:00
|
|
|
|
<a
|
|
|
|
|
|
v-if="run.can_restart_from_scratch"
|
|
|
|
|
|
class="dropdown-item"
|
2019-04-08 15:45:30 +00:00
|
|
|
|
@click="restartRun(run.id, true)"
|
2019-03-29 10:25:29 +00:00
|
|
|
|
>From start</a>
|
|
|
|
|
|
<a
|
|
|
|
|
|
v-if="run.can_restart_from_failed_tasks"
|
|
|
|
|
|
class="dropdown-item"
|
2019-04-08 15:45:30 +00:00
|
|
|
|
@click="restartRun(run.id)"
|
2019-03-29 10:25:29 +00:00
|
|
|
|
>From failed tasks</a>
|
2018-12-09 13:21:20 +00:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2019-05-15 12:44:35 +00:00
|
|
|
|
<button
|
|
|
|
|
|
class="button is-danger"
|
|
|
|
|
|
v-if="run.phase == 'queued'"
|
|
|
|
|
|
@click="cancelRun(run.id)"
|
|
|
|
|
|
>Cancel</button>
|
2018-12-09 13:21:20 +00:00
|
|
|
|
<button
|
|
|
|
|
|
class="button is-danger"
|
|
|
|
|
|
v-if="run.phase == 'running'"
|
2019-05-15 12:50:08 +00:00
|
|
|
|
:disabled="run.stopping"
|
2019-04-08 15:45:30 +00:00
|
|
|
|
@click="stopRun(run.id)"
|
2018-12-09 13:21:20 +00:00
|
|
|
|
>Stop</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="item-content columns">
|
|
|
|
|
|
<div class="commitmessage column">{{run.annotations.message}}</div>
|
|
|
|
|
|
<div class="source-info column">
|
|
|
|
|
|
<a :href="run.annotations.commit_link" class="commit" target="_blank">
|
|
|
|
|
|
<i class="mdi mdi-source-commit mdi-rotate-90"></i>
|
|
|
|
|
|
<span>{{run.annotations.commit_sha.substring(0,8)}}</span>
|
|
|
|
|
|
</a>
|
|
|
|
|
|
<a
|
|
|
|
|
|
v-if="run.annotations.event_type == 'push'"
|
|
|
|
|
|
:href="run.annotations.branch_link"
|
|
|
|
|
|
class="commit"
|
|
|
|
|
|
target="_blank"
|
|
|
|
|
|
>
|
|
|
|
|
|
<i class="mdi mdi-source-branch"></i>
|
|
|
|
|
|
<span>{{run.annotations.branch}}</span>
|
|
|
|
|
|
</a>
|
|
|
|
|
|
<a
|
|
|
|
|
|
v-else-if="run.annotations.event_type == 'tag'"
|
|
|
|
|
|
:href="run.annotations.tag_link"
|
|
|
|
|
|
class="commit"
|
|
|
|
|
|
target="_blank"
|
|
|
|
|
|
>
|
|
|
|
|
|
<i class="mdi mdi-tag"></i>
|
|
|
|
|
|
<span>{{run.annotations.tag}}</span>
|
|
|
|
|
|
</a>
|
|
|
|
|
|
<a
|
|
|
|
|
|
v-else-if="run.annotations.event_type == 'pull_request'"
|
|
|
|
|
|
:href="run.annotations.pull_request_link"
|
|
|
|
|
|
class="commit"
|
|
|
|
|
|
target="_blank"
|
|
|
|
|
|
>
|
|
|
|
|
|
<i class="mdi mdi-source-pull"></i>
|
|
|
|
|
|
<span>PR #{{run.annotations.pull_request_id}}</span>
|
|
|
|
|
|
</a>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2019-05-15 12:59:52 +00:00
|
|
|
|
<div v-if="stopRunError" class="message is-danger">
|
|
|
|
|
|
<div class="message-body">{{ stopRunError }}</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div v-if="cancelRunError" class="message is-danger">
|
|
|
|
|
|
<div class="message-body">{{ cancelRunError }}</div>
|
|
|
|
|
|
</div>
|
2018-12-09 13:21:20 +00:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
2019-05-17 15:00:46 +00:00
|
|
|
|
import vClickOutside from "v-click-outside";
|
|
|
|
|
|
|
2019-05-15 12:44:35 +00:00
|
|
|
|
import { cancelRun, stopRun, restartRun } from "@/util/data.js";
|
2018-12-09 13:21:20 +00:00
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
|
name: "RunDetail",
|
2019-05-17 15:00:46 +00:00
|
|
|
|
directives: {
|
|
|
|
|
|
clickOutside: vClickOutside.directive
|
|
|
|
|
|
},
|
2018-12-09 13:21:20 +00:00
|
|
|
|
props: {
|
|
|
|
|
|
run: Object
|
|
|
|
|
|
},
|
|
|
|
|
|
data() {
|
2019-05-08 15:12:56 +00:00
|
|
|
|
return {
|
2019-05-15 12:59:52 +00:00
|
|
|
|
stopRunError: null,
|
|
|
|
|
|
cancelRunError: null,
|
2019-05-08 15:12:56 +00:00
|
|
|
|
dropdownActive: false
|
|
|
|
|
|
};
|
2018-12-09 13:21:20 +00:00
|
|
|
|
},
|
|
|
|
|
|
methods: {
|
2019-05-15 12:59:52 +00:00
|
|
|
|
resetErrors() {
|
|
|
|
|
|
this.stopRunError = null;
|
|
|
|
|
|
this.cancelRunError = null;
|
|
|
|
|
|
},
|
2019-05-08 15:12:56 +00:00
|
|
|
|
toggleDropdown() {
|
|
|
|
|
|
this.dropdownActive = !this.dropdownActive;
|
|
|
|
|
|
},
|
2018-12-09 13:21:20 +00:00
|
|
|
|
stillRunning(run) {
|
|
|
|
|
|
return run.result != "unknown" && run.phase == "running";
|
|
|
|
|
|
},
|
|
|
|
|
|
runStatus(run) {
|
|
|
|
|
|
if (run.phase != "finished") return run.phase;
|
|
|
|
|
|
if (run.result != "unknown") return run.result;
|
|
|
|
|
|
if (run.stopping) return "stopping";
|
|
|
|
|
|
|
|
|
|
|
|
return run.result;
|
|
|
|
|
|
},
|
|
|
|
|
|
runResultClass(run) {
|
2019-04-02 16:08:03 +00:00
|
|
|
|
let status = this.runStatus(run);
|
2018-12-09 13:21:20 +00:00
|
|
|
|
|
2019-04-10 09:21:18 +00:00
|
|
|
|
if (status == "setuperror") return "setuperror";
|
2018-12-09 13:21:20 +00:00
|
|
|
|
if (status == "queued") return "unknown";
|
|
|
|
|
|
if (status == "cancelled") return "failed";
|
|
|
|
|
|
if (status == "running") return "running";
|
|
|
|
|
|
if (status == "stopping") return "failed";
|
|
|
|
|
|
if (status == "stopped") return "failed";
|
|
|
|
|
|
if (status == "success") return "success";
|
|
|
|
|
|
if (status == "failed") return "failed";
|
|
|
|
|
|
return "unknown";
|
|
|
|
|
|
},
|
|
|
|
|
|
taskClass(task) {
|
|
|
|
|
|
if (task.status == "success") return "success";
|
|
|
|
|
|
if (task.status == "failed") return "failed";
|
|
|
|
|
|
if (task.status == "stopped") return "failed";
|
|
|
|
|
|
if (task.status == "running") return "running";
|
|
|
|
|
|
return "unknown";
|
|
|
|
|
|
},
|
2019-05-15 12:59:52 +00:00
|
|
|
|
async stopRun(runid) {
|
|
|
|
|
|
this.resetErrors();
|
|
|
|
|
|
|
|
|
|
|
|
let { error } = await stopRun(runid);
|
|
|
|
|
|
if (error) {
|
|
|
|
|
|
this.cancelRunError = error;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-05-15 12:50:08 +00:00
|
|
|
|
this.run.stopping = true;
|
|
|
|
|
|
},
|
2019-05-15 12:59:52 +00:00
|
|
|
|
async cancelRun(runid) {
|
|
|
|
|
|
this.resetErrors();
|
|
|
|
|
|
|
|
|
|
|
|
let { error } = await cancelRun(runid);
|
|
|
|
|
|
if (error) {
|
|
|
|
|
|
this.cancelRunError = error;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-05-15 12:55:00 +00:00
|
|
|
|
this.run.phase = "cancelled";
|
|
|
|
|
|
},
|
2019-05-08 15:12:56 +00:00
|
|
|
|
restartRun(runid, fromStart) {
|
|
|
|
|
|
this.dropdownActive = false;
|
|
|
|
|
|
restartRun(runid, fromStart);
|
|
|
|
|
|
}
|
2018-12-09 13:21:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
|
@import "@/css/_variables.scss";
|
|
|
|
|
|
|
|
|
|
|
|
.run {
|
|
|
|
|
|
margin-bottom: 2rem;
|
|
|
|
|
|
|
|
|
|
|
|
.run-content {
|
|
|
|
|
|
margin-bottom: 5px;
|
|
|
|
|
|
border: 1px solid $grey-lighter;
|
|
|
|
|
|
border-left: 0 solid;
|
|
|
|
|
|
display: block;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
padding: 10px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.run-title {
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
padding-left: 5px;
|
|
|
|
|
|
margin-bottom: 25px;
|
|
|
|
|
|
|
|
|
|
|
|
.run-name {
|
|
|
|
|
|
padding-left: 5px;
|
|
|
|
|
|
font-size: 1.5rem;
|
|
|
|
|
|
padding-right: 1rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.success {
|
|
|
|
|
|
border-left: 0px solid $green;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.failed {
|
|
|
|
|
|
border-left: 5px solid $red;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.running {
|
|
|
|
|
|
border-left: 5px solid $blue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.unknown {
|
|
|
|
|
|
border-left: 5px solid $grey-lighter;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.run-actions {
|
|
|
|
|
|
text-align: right;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.item-content {
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.success {
|
|
|
|
|
|
border-left: 5px solid $green;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.failed {
|
|
|
|
|
|
border-left: 5px solid $red;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.running {
|
|
|
|
|
|
border-left: 5px solid $blue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.unknown {
|
|
|
|
|
|
border-left: 5px solid $grey-lighter;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-04-10 09:21:18 +00:00
|
|
|
|
.setuperror {
|
|
|
|
|
|
border-left: 5px solid $yellow;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-12-09 13:21:20 +00:00
|
|
|
|
.name {
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.commitmessage {
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.stillrunning {
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.source-info {
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
|
|
|
|
|
|
|
a {
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.commit {
|
|
|
|
|
|
display: block;
|
|
|
|
|
|
font-size: 0.8rem;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|