aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHesterG <hestergong@gmail.com>2023-05-22 12:17:24 +0800
committerGitHub <noreply@github.com>2023-05-22 12:17:24 +0800
commitda461b5a085c0fbf705df9a751159d13bee7139a (patch)
tree87d3ca4d682fda67e4502f83796e8f34b348d105
parentcdb088cec288a20e14240f86a689dd14f4cd603b (diff)
downloadgitea-da461b5a085c0fbf705df9a751159d13bee7139a.tar.gz
gitea-da461b5a085c0fbf705df9a751159d13bee7139a.zip
Improvements for action detail page (#24718)
Close #24625 Main changes: 1. For the left panel, show rerun icon only on hover, and add style when the job is selected, and removed icon on the "rerun all" button and modify the text on the button https://github.com/go-gitea/gitea/assets/17645053/cc437a17-d2e9-4f1b-a8cf-f56e53962767 2. Adjust fonts, and add on hover effects to the log lines. And add loading effect when the job is done and the job step log is expanded for the first time. (With reference to github) https://github.com/go-gitea/gitea/assets/17645053/2808d77d-f402-4fb0-8819-7aa0a018cf0c 3. Add `gt-ellipsis` to `step-summary-msg` and `job-brief-name` <img width="898" alt="ellipsis" src="https://github.com/go-gitea/gitea/assets/17645053/e2fb7049-3125-4252-970d-15b0751febc7"> 4. Fixed https://github.com/go-gitea/gitea/issues/24625#issuecomment-1541380010 by adding explicit conditions to `ActionRunStatus.vue` and `status.tmpl` 5. Adjust some css styles --------- Co-authored-by: silverwind <me@silverwind.io>
-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);