aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--options/locale/locale_en-US.ini1
-rw-r--r--templates/repo/actions/status.tmpl5
-rw-r--r--templates/repo/actions/view.tmpl1
-rw-r--r--web_src/css/base.css1
-rw-r--r--web_src/js/components/ActionRunStatus.vue5
-rw-r--r--web_src/js/components/RepoActionView.vue171
6 files changed, 130 insertions, 54 deletions
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index e5742157d8..80ccecbce1 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -80,6 +80,7 @@ milestones = Milestones
ok = OK
cancel = Cancel
rerun = Re-run
+rerun_all = Re-run all jobs
save = Save
add = Add
add_all = Add All
diff --git a/templates/repo/actions/status.tmpl b/templates/repo/actions/status.tmpl
index ab2ee8482c..cdc747aa8b 100644
--- a/templates/repo/actions/status.tmpl
+++ b/templates/repo/actions/status.tmpl
@@ -1,5 +1,6 @@
<!-- This template should be kept the same as web_src/js/components/ActionRunStatus.vue
Please also update the vue file above if this template is modified.
+ action status accepted: success, skipped, waiting, blocked, running, failure, cancelled, unknown
-->
{{- $size := 16 -}}
{{- if .size -}}
@@ -11,7 +12,7 @@
{{- $className = .className -}}
{{- end -}}
-<span data-tooltip-content="{{.locale.Tr (printf "actions.status.%s" .status)}}">
+<span class="gt-df gt-ac" data-tooltip-content="{{.locale.Tr (printf "actions.status.%s" .status)}}">
{{if eq .status "success"}}
{{svg "octicon-check-circle-fill" $size (printf "text green %s" $className)}}
{{else if eq .status "skipped"}}
@@ -22,7 +23,7 @@
{{svg "octicon-blocked" $size (printf "text yellow %s" $className)}}
{{else if eq .status "running"}}
{{svg "octicon-meter" $size (printf "text yellow job-status-rotate %s" $className)}}
-{{else}}
+{{else if or (eq .status "failure") or (eq .status "cancelled") or (eq .status "unknown")}}
{{svg "octicon-x-circle-fill" $size (printf "text red %s" $className)}}
{{end}}
</span>
diff --git a/templates/repo/actions/view.tmpl b/templates/repo/actions/view.tmpl
index 8d6559ee98..3a3a069cbc 100644
--- a/templates/repo/actions/view.tmpl
+++ b/templates/repo/actions/view.tmpl
@@ -9,6 +9,7 @@
data-locale-approve="{{.locale.Tr "repo.diff.review.approve"}}"
data-locale-cancel="{{.locale.Tr "cancel"}}"
data-locale-rerun="{{.locale.Tr "rerun"}}"
+ data-locale-rerun-all="{{.locale.Tr "rerun_all"}}"
data-locale-status-unknown="{{.locale.Tr "actions.status.unknown"}}"
data-locale-status-waiting="{{.locale.Tr "actions.status.waiting"}}"
data-locale-status-running="{{.locale.Tr "actions.status.running"}}"
diff --git a/web_src/css/base.css b/web_src/css/base.css
index eb12ffef7a..4b9f1eef22 100644
--- a/web_src/css/base.css
+++ b/web_src/css/base.css
@@ -71,6 +71,7 @@
/* console colors */
--color-console-fg: #ffffff;
--color-console-bg: #171717;
+ --color-console-hover-bg: #ffffff16;
/* named colors */
--color-red: #db2828;
--color-orange: #f2711c;
diff --git a/web_src/js/components/ActionRunStatus.vue b/web_src/js/components/ActionRunStatus.vue
index 0786cb60a9..bddf307a1b 100644
--- a/web_src/js/components/ActionRunStatus.vue
+++ b/web_src/js/components/ActionRunStatus.vue
@@ -1,14 +1,15 @@
<!-- This vue should be kept the same as templates/repo/actions/status.tmpl
Please also update the template file above if this vue is modified.
+ action status accepted: success, skipped, waiting, blocked, running, failure, cancelled, unknown
-->
<template>
- <span :data-tooltip-content="localeStatus" v-if="status">
+ <span class="gt-df gt-ac" :data-tooltip-content="localeStatus" v-if="status">
<SvgIcon name="octicon-check-circle-fill" class="text green" :size="size" :class-name="className" v-if="status === 'success'"/>
<SvgIcon name="octicon-skip" class="text grey" :size="size" :class-name="className" v-else-if="status === 'skipped'"/>
<SvgIcon name="octicon-clock" class="text yellow" :size="size" :class-name="className" v-else-if="status === 'waiting'"/>
<SvgIcon name="octicon-blocked" class="text yellow" :size="size" :class-name="className" v-else-if="status === 'blocked'"/>
<SvgIcon name="octicon-meter" class="text yellow" :size="size" :class-name="'job-status-rotate ' + className" v-else-if="status === 'running'"/>
- <SvgIcon name="octicon-x-circle-fill" class="text red" :size="size" v-else/>
+ <SvgIcon name="octicon-x-circle-fill" class="text red" :size="size" v-else-if="['failure', 'cancelled', 'unknown'].includes(status)" />
</span>
</template>
diff --git a/web_src/js/components/RepoActionView.vue b/web_src/js/components/RepoActionView.vue
index 28adfbc6ec..b2fd63dd18 100644
--- a/web_src/js/components/RepoActionView.vue
+++ b/web_src/js/components/RepoActionView.vue
@@ -1,28 +1,30 @@
<template>
- <div class="action-view-container">
+ <div class="ui container action-view-container">
<div class="action-view-header">
<div class="action-info-summary">
- <ActionRunStatus :locale-status="locale.status[run.status]" :status="run.status" :size="20"/>
- <div class="action-title">
- {{ run.title }}
+ <div class="action-info-summary-title">
+ <ActionRunStatus :locale-status="locale.status[run.status]" :status="run.status" :size="20"/>
+ <h2 class="action-info-summary-title-text">
+ {{ run.title }}
+ </h2>
</div>
<button class="ui basic small compact button primary" @click="approveRun()" v-if="run.canApprove">
- <SvgIcon class="gt-mr-2" name="octicon-play" :size="20"/> {{ locale.approve }}
+ {{ locale.approve }}
</button>
<button class="ui basic small compact button red" @click="cancelRun()" v-else-if="run.canCancel">
- <SvgIcon class="gt-mr-2" name="octicon-x-circle-fill" :size="20"/> {{ locale.cancel }}
+ {{ locale.cancel }}
</button>
<button class="ui basic small compact button secondary" @click="rerun()" v-else-if="run.canRerun">
- <SvgIcon class="gt-mr-2" name="octicon-sync" :size="20"/> {{ locale.rerun }}
+ {{ locale.rerun_all }}
</button>
</div>
<div class="action-commit-summary">
{{ run.commit.localeCommit }}
<a :href="run.commit.link">{{ run.commit.shortSHA }}</a>
- &nbsp;<span class="ui label" v-if="run.commit.shortSHA">
+ <span class="ui label" v-if="run.commit.shortSHA">
<a :href="run.commit.branch.link">{{ run.commit.branch.name }}</a>
</span>
- &nbsp;{{ run.commit.localePushedBy }}
+ {{ run.commit.localePushedBy }}
<a :href="run.commit.pusher.link">{{ run.commit.pusher.displayName }}</a>
</div>
</div>
@@ -30,15 +32,15 @@
<div class="action-view-left">
<div class="job-group-section">
<div class="job-brief-list">
- <div class="job-brief-item" v-for="(job, index) in run.jobs" :key="job.id">
+ <div class="job-brief-item" :class="parseInt(jobIndex) === index ? 'selected' : ''" v-for="(job, index) in run.jobs" :key="job.id" @mouseenter="onHoverRerunIndex = job.id" @mouseleave="onHoverRerunIndex = -1">
<a class="job-brief-link" :href="run.link+'/jobs/'+index">
<ActionRunStatus :locale-status="locale.status[job.status]" :status="job.status"/>
- <span class="ui text gt-mx-3">{{ job.name }}</span>
+ <span class="job-brief-name gt-mx-3 gt-ellipsis">{{ job.name }}</span>
</a>
- <span class="step-summary-duration">{{ job.duration }}</span>
- <button :data-tooltip-content="locale.rerun" class="job-brief-rerun" @click="rerunJob(index)" v-if="job.canRerun">
- <SvgIcon name="octicon-sync" class="ui text black"/>
- </button>
+ <span class="job-brief-info">
+ <span class="step-summary-duration">{{ job.duration }}</span>
+ <SvgIcon name="octicon-sync" role="button" :data-tooltip-content="locale.rerun" class="job-brief-rerun gt-mx-3" @click="rerunJob(index)" v-if="job.canRerun && onHoverRerunIndex === job.id"/>
+ </span>
</div>
</div>
</div>
@@ -58,21 +60,24 @@
<div class="action-view-right">
<div class="job-info-header">
- <div class="job-info-header-title">
+ <h3 class="job-info-header-title">
{{ currentJob.title }}
- </div>
- <div class="job-info-header-detail">
+ </h3>
+ <p class="job-info-header-detail">
{{ currentJob.detail }}
- </div>
+ </p>
</div>
<div class="job-step-container">
<div class="job-step-section" v-for="(jobStep, i) in currentJob.steps" :key="i">
- <div class="job-step-summary" @click.stop="toggleStepLogs(i)">
- <SvgIcon :name="currentJobStepsStates[i].expanded ? 'octicon-chevron-down': 'octicon-chevron-right'" class="gt-mr-3"/>
-
+ <div class="job-step-summary" @click.stop="toggleStepLogs(i)" :class="currentJobStepsStates[i].expanded ? 'selected' : ''">
+ <!-- If the job is done and the job step log is loaded for the first time, show the loading icon
+ currentJobStepsStates[i].cursor === null means the log is loaded for the first time
+ -->
+ <SvgIcon v-if="isDone(run.status) && currentJobStepsStates[i].expanded && currentJobStepsStates[i].cursor === null" name="octicon-sync" class="gt-mr-3 job-status-rotate"/>
+ <SvgIcon v-else :name="currentJobStepsStates[i].expanded ? 'octicon-chevron-down': 'octicon-chevron-right'" class="gt-mr-3"/>
<ActionRunStatus :status="jobStep.status" class="gt-mr-3"/>
- <span class="step-summary-msg">{{ jobStep.summary }}</span>
+ <span class="step-summary-msg gt-ellipsis">{{ jobStep.summary }}</span>
<span class="step-summary-duration">{{ jobStep.duration }}</span>
</div>
@@ -115,6 +120,7 @@ const sfc = {
intervalID: null,
currentJobStepsStates: [],
artifacts: [],
+ onHoverRerunIndex: -1,
// provided by backend
run: {
@@ -295,6 +301,7 @@ const sfc = {
// sync the currentJobStepsStates to store the job step states
for (let i = 0; i < this.currentJob.steps.length; i++) {
if (!this.currentJobStepsStates[i]) {
+ // initial states for job steps
this.currentJobStepsStates[i] = {cursor: null, expanded: false};
}
}
@@ -325,6 +332,10 @@ const sfc = {
body,
});
},
+
+ isDone(status) {
+ return ['success', 'skipped', 'failure', 'cancelled'].includes(status);
+ }
},
};
@@ -348,6 +359,7 @@ export function initRepositoryActionView() {
cancel: el.getAttribute('data-locale-cancel'),
rerun: el.getAttribute('data-locale-rerun'),
artifactsTitle: el.getAttribute('data-locale-artifacts-title'),
+ rerun_all: el.getAttribute('data-locale-rerun-all'),
status: {
unknown: el.getAttribute('data-locale-status-unknown'),
waiting: el.getAttribute('data-locale-status-waiting'),
@@ -417,24 +429,30 @@ export function ansiLogToHTML(line) {
/* action view header */
.action-view-header {
- margin: 0 20px 20px 20px;
+ margin: 20px 0px;
}
.action-info-summary {
- font-size: 150%;
- height: 20px;
display: flex;
align-items: center;
margin-top: 1rem;
+ justify-content: space-between;
+}
+
+.action-info-summary-title {
+ display: flex;
}
-.action-info-summary .action-title {
- padding: 0 5px;
+.action-info-summary-title-text {
+ font-size: 20px;
+ margin: 0 0 0 5px;
flex: 1;
}
.action-commit-summary {
- padding: 10px 10px;
+ display: flex;
+ gap: 5px;
+ margin: 10px 0px 10px 25px;
}
/* ================ */
@@ -444,7 +462,6 @@ export function ansiLogToHTML(line) {
width: 30%;
max-width: 400px;
overflow-y: scroll;
- margin-left: 10px;
}
.job-group-section .job-group-summary {
@@ -473,42 +490,64 @@ export function ansiLogToHTML(line) {
padding-right: 3px;
}
-.job-group-section .job-brief-list .job-brief-item {
+.job-brief-item {
margin: 5px 0;
padding: 10px;
background: var(--color-info-bg);
border-radius: 5px;
text-decoration: none;
display: flex;
- justify-items: center;
flex-wrap: nowrap;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.job-brief-item:hover {
+ background-color: var(--color-secondary);
+}
+
+.job-brief-item.selected {
+ font-weight: var(--font-weight-bold);
+ background-color: var(--color-secondary-dark-1);
+}
+
+.job-brief-item:first-of-type {
+ margin-top: 0;
}
-.job-group-section .job-brief-list .job-brief-item .job-brief-rerun {
- float: right;
- border: none;
- background-color: transparent;
- outline: none;
+.job-brief-item .job-brief-rerun {
cursor: pointer;
transition: transform 0.2s;
}
-.job-group-section .job-brief-list .job-brief-item .job-brief-rerun:hover {
+.job-brief-item .job-brief-rerun:hover {
transform: scale(130%);
}
-.job-group-section .job-brief-list .job-brief-item .job-brief-link {
- flex-grow: 1;
+.job-brief-item .job-brief-link {
display: flex;
+ width: 100%;
}
-.job-group-section .job-brief-list .job-brief-item .job-brief-link span {
+.job-brief-item .job-brief-link span {
display: flex;
align-items: center;
}
-.job-group-section .job-brief-list .job-brief-item:hover {
- background-color: var(--color-secondary);
+.job-brief-item .job-brief-link .job-brief-name {
+ display: block;
+ width: 70%;
+ color: var(--color-text);
+}
+
+.job-brief-item .job-brief-link:hover {
+ text-decoration: none;
+}
+
+.job-brief-item .job-brief-info {
+ display: flex;
+ align-items: center;
+ width: 55px;
}
/* ================ */
@@ -517,21 +556,27 @@ export function ansiLogToHTML(line) {
.action-view-right {
flex: 1;
background-color: var(--color-console-bg);
- color: var(--color-console-fg);
+ color: var(--color-secondary-dark-2);
max-height: 100%;
- margin-right: 10px;
+ width: 70%;
display: flex;
flex-direction: column;
}
-.job-info-header .job-info-header-title {
- font-size: 150%;
+.job-info-header {
padding: 10px;
+ border-bottom: 1px solid var(--color-grey);
+}
+
+.job-info-header .job-info-header-title {
+ color: var(--color-console-fg);
+ font-size: 16px;
+ margin: 0;
}
.job-info-header .job-info-header-detail {
- padding: 0 10px 10px;
- border-bottom: 1px solid var(--color-grey);
+ color: var(--color-secondary-dark-3);
+ font-size: 12px;
}
.job-step-container {
@@ -543,6 +588,8 @@ export function ansiLogToHTML(line) {
cursor: pointer;
padding: 5px 10px;
display: flex;
+ align-items: center;
+ user-select: none;
}
.job-step-container .job-step-summary .step-summary-msg {
@@ -553,8 +600,25 @@ export function ansiLogToHTML(line) {
margin-left: 16px;
}
-.job-step-container .job-step-summary:hover {
+.job-step-container .job-step-summary:hover,
+.job-step-container .job-step-summary.selected {
+ color: var(--color-console-fg);
background-color: var(--color-black-light);
+ border-radius: 5px;
+}
+
+@media (max-width: 768px) {
+ .action-view-body {
+ flex-direction: column;
+ }
+ .action-view-left, .action-view-right {
+ width: 100%;
+ }
+
+ .action-view-left {
+ max-width: none;
+ overflow-y: hidden;
+ }
}
</style>
@@ -576,12 +640,19 @@ export function ansiLogToHTML(line) {
.job-step-section .job-step-logs {
font-family: monospace, monospace;
+ margin: 8px 0px;
+ font-size: 12px;
}
.job-step-section .job-step-logs .job-log-line {
display: flex;
}
+.job-step-section .job-step-logs .job-log-line:hover {
+ color: var(--color-console-fg);
+ background-color: var(--color-console-hover-bg);
+}
+
.job-step-section .job-step-logs .job-log-line .line-num {
width: 48px;
color: var(--color-grey-light);