Skip to content

Commit 6279646

Browse files
Add auto-expanding running actions step (#30058)
Auto-expands the currently running action step. --------- Co-authored-by: wxiaoguang <[email protected]>
1 parent daf2776 commit 6279646

File tree

6 files changed

+113
-56
lines changed

6 files changed

+113
-56
lines changed

options/locale/locale_en-US.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3773,6 +3773,9 @@ variables.creation.success = The variable "%s" has been added.
37733773
variables.update.failed = Failed to edit variable.
37743774
variables.update.success = The variable has been edited.
37753775

3776+
logs.always_auto_scroll = Always auto scroll logs
3777+
logs.always_expand_running = Always expand running logs
3778+
37763779
[projects]
37773780
deleted.display_name = Deleted Project
37783781
type-1.display_name = Individual Project

routers/web/devtest/mock_actions.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ func generateMockStepsLog(logCur actions.LogCursor) (stepsLog []*actions.ViewSte
3131
"##[endgroup]",
3232
}
3333
cur := logCur.Cursor // usually the cursor is the "file offset", but here we abuse it as "line number" to make the mock easier, intentionally
34-
for i := 0; i < util.Iif(logCur.Step == 0, 3, 1); i++ {
34+
mockCount := util.Iif(logCur.Step == 0, 3, 1)
35+
if logCur.Step == 1 && logCur.Cursor == 0 {
36+
mockCount = 30 // for the first batch, return as many as possible to test the auto-expand and auto-scroll
37+
}
38+
for i := 0; i < mockCount; i++ {
3539
logStr := mockedLogs[int(cur)%len(mockedLogs)]
3640
cur++
3741
logStr = strings.ReplaceAll(logStr, "{step}", fmt.Sprintf("%d", logCur.Step))
@@ -56,6 +60,21 @@ func MockActionsRunsJobs(ctx *context.Context) {
5660
resp.State.Run.Status = actions_model.StatusRunning.String()
5761
resp.State.Run.CanCancel = true
5862
resp.State.Run.CanDeleteArtifact = true
63+
resp.State.Run.WorkflowID = "workflow-id"
64+
resp.State.Run.WorkflowLink = "./workflow-link"
65+
resp.State.Run.Commit = actions.ViewCommit{
66+
ShortSha: "ccccdddd",
67+
Link: "./commit-link",
68+
Pusher: actions.ViewUser{
69+
DisplayName: "pusher user",
70+
Link: "./pusher-link",
71+
},
72+
Branch: actions.ViewBranch{
73+
Name: "commit-branch",
74+
Link: "./branch-link",
75+
IsDeleted: false,
76+
},
77+
}
5978
resp.Artifacts = append(resp.Artifacts, &actions.ArtifactsViewItem{
6079
Name: "artifact-a",
6180
Size: 100 * 1024,
Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,9 @@
11
{{template "base/head" .}}
22
<div class="page-content">
3-
<div id="repo-action-view"
4-
data-run-index="1"
5-
data-job-index="2"
6-
data-actions-url="{{AppSubUrl}}/devtest/actions-mock"
7-
data-locale-approve="approve"
8-
data-locale-cancel="cancel"
9-
data-locale-rerun="re-run"
10-
data-locale-rerun-all="re-run all"
11-
data-locale-runs-scheduled="scheduled"
12-
data-locale-runs-commit="commit"
13-
data-locale-runs-pushed-by="pushed by"
14-
data-locale-status-unknown="unknown"
15-
data-locale-status-waiting="waiting"
16-
data-locale-status-running="running"
17-
data-locale-status-success="success"
18-
data-locale-status-failure="failure"
19-
data-locale-status-cancelled="cancelled"
20-
data-locale-status-skipped="skipped"
21-
data-locale-status-blocked="blocked"
22-
data-locale-artifacts-title="artifacts"
23-
data-locale-confirm-delete-artifact="confirm delete artifact"
24-
data-locale-show-timestamps="show timestamps"
25-
data-locale-show-log-seconds="show log seconds"
26-
data-locale-show-full-screen="show full screen"
27-
data-locale-download-logs="download logs"
28-
></div>
3+
{{template "repo/actions/view_component" (dict
4+
"RunIndex" 1
5+
"JobIndex" 2
6+
"ActionsURL" (print AppSubUrl "/devtest/actions-mock")
7+
)}}
298
</div>
309
{{template "base/footer" .}}

templates/repo/actions/view.tmpl

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,11 @@
22

33
<div class="page-content repository">
44
{{template "repo/header" .}}
5-
<div id="repo-action-view"
6-
data-run-index="{{.RunIndex}}"
7-
data-job-index="{{.JobIndex}}"
8-
data-actions-url="{{.ActionsURL}}"
9-
data-locale-approve="{{ctx.Locale.Tr "repo.diff.review.approve"}}"
10-
data-locale-cancel="{{ctx.Locale.Tr "cancel"}}"
11-
data-locale-rerun="{{ctx.Locale.Tr "rerun"}}"
12-
data-locale-rerun-all="{{ctx.Locale.Tr "rerun_all"}}"
13-
data-locale-runs-scheduled="{{ctx.Locale.Tr "actions.runs.scheduled"}}"
14-
data-locale-runs-commit="{{ctx.Locale.Tr "actions.runs.commit"}}"
15-
data-locale-runs-pushed-by="{{ctx.Locale.Tr "actions.runs.pushed_by"}}"
16-
data-locale-status-unknown="{{ctx.Locale.Tr "actions.status.unknown"}}"
17-
data-locale-status-waiting="{{ctx.Locale.Tr "actions.status.waiting"}}"
18-
data-locale-status-running="{{ctx.Locale.Tr "actions.status.running"}}"
19-
data-locale-status-success="{{ctx.Locale.Tr "actions.status.success"}}"
20-
data-locale-status-failure="{{ctx.Locale.Tr "actions.status.failure"}}"
21-
data-locale-status-cancelled="{{ctx.Locale.Tr "actions.status.cancelled"}}"
22-
data-locale-status-skipped="{{ctx.Locale.Tr "actions.status.skipped"}}"
23-
data-locale-status-blocked="{{ctx.Locale.Tr "actions.status.blocked"}}"
24-
data-locale-artifacts-title="{{ctx.Locale.Tr "artifacts"}}"
25-
data-locale-confirm-delete-artifact="{{ctx.Locale.Tr "confirm_delete_artifact"}}"
26-
data-locale-show-timestamps="{{ctx.Locale.Tr "show_timestamps"}}"
27-
data-locale-show-log-seconds="{{ctx.Locale.Tr "show_log_seconds"}}"
28-
data-locale-show-full-screen="{{ctx.Locale.Tr "show_full_screen"}}"
29-
data-locale-download-logs="{{ctx.Locale.Tr "download_logs"}}"
30-
>
31-
</div>
5+
{{template "repo/actions/view_component" (dict
6+
"RunIndex" .RunIndex
7+
"JobIndex" .JobIndex
8+
"ActionsURL" .ActionsURL
9+
)}}
3210
</div>
3311

3412
{{template "base/footer" .}}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<div id="repo-action-view"
2+
data-run-index="{{.RunIndex}}"
3+
data-job-index="{{.JobIndex}}"
4+
data-actions-url="{{.ActionsURL}}"
5+
6+
data-locale-approve="{{ctx.Locale.Tr "repo.diff.review.approve"}}"
7+
data-locale-cancel="{{ctx.Locale.Tr "cancel"}}"
8+
data-locale-rerun="{{ctx.Locale.Tr "rerun"}}"
9+
data-locale-rerun-all="{{ctx.Locale.Tr "rerun_all"}}"
10+
data-locale-runs-scheduled="{{ctx.Locale.Tr "actions.runs.scheduled"}}"
11+
data-locale-runs-commit="{{ctx.Locale.Tr "actions.runs.commit"}}"
12+
data-locale-runs-pushed-by="{{ctx.Locale.Tr "actions.runs.pushed_by"}}"
13+
data-locale-status-unknown="{{ctx.Locale.Tr "actions.status.unknown"}}"
14+
data-locale-status-waiting="{{ctx.Locale.Tr "actions.status.waiting"}}"
15+
data-locale-status-running="{{ctx.Locale.Tr "actions.status.running"}}"
16+
data-locale-status-success="{{ctx.Locale.Tr "actions.status.success"}}"
17+
data-locale-status-failure="{{ctx.Locale.Tr "actions.status.failure"}}"
18+
data-locale-status-cancelled="{{ctx.Locale.Tr "actions.status.cancelled"}}"
19+
data-locale-status-skipped="{{ctx.Locale.Tr "actions.status.skipped"}}"
20+
data-locale-status-blocked="{{ctx.Locale.Tr "actions.status.blocked"}}"
21+
data-locale-artifacts-title="{{ctx.Locale.Tr "artifacts"}}"
22+
data-locale-confirm-delete-artifact="{{ctx.Locale.Tr "confirm_delete_artifact"}}"
23+
data-locale-show-timestamps="{{ctx.Locale.Tr "show_timestamps"}}"
24+
data-locale-show-log-seconds="{{ctx.Locale.Tr "show_log_seconds"}}"
25+
data-locale-show-full-screen="{{ctx.Locale.Tr "show_full_screen"}}"
26+
data-locale-download-logs="{{ctx.Locale.Tr "download_logs"}}"
27+
data-locale-logs-always-auto-scroll="{{ctx.Locale.Tr "actions.logs.always_auto_scroll"}}"
28+
data-locale-logs-always-expand-running="{{ctx.Locale.Tr "actions.logs.always_expand_running"}}"
29+
>
30+
</div>

web_src/js/components/RepoActionView.vue

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,20 @@ function isLogElementInViewport(el: HTMLElement): boolean {
4343
return rect.top >= 0 && rect.bottom <= window.innerHeight; // only check height but not width
4444
}
4545
46+
type LocaleStorageOptions = {
47+
autoScroll: boolean;
48+
expandRunning: boolean;
49+
};
50+
51+
function getLocaleStorageOptions(): LocaleStorageOptions {
52+
try {
53+
const optsJson = localStorage.getItem('actions-view-options');
54+
if (optsJson) return JSON.parse(optsJson);
55+
} catch {}
56+
// if no options in localStorage, or failed to parse, return default options
57+
return {autoScroll: true, expandRunning: false};
58+
}
59+
4660
const sfc = {
4761
name: 'RepoActionView',
4862
components: {
@@ -56,7 +70,17 @@ const sfc = {
5670
locale: Object,
5771
},
5872
73+
watch: {
74+
optionAlwaysAutoScroll() {
75+
this.saveLocaleStorageOptions();
76+
},
77+
optionAlwaysExpandRunning() {
78+
this.saveLocaleStorageOptions();
79+
},
80+
},
81+
5982
data() {
83+
const {autoScroll, expandRunning} = getLocaleStorageOptions();
6084
return {
6185
// internal state
6286
loadingAbortController: null,
@@ -70,6 +94,8 @@ const sfc = {
7094
'log-time-stamp': false,
7195
'log-time-seconds': false,
7296
},
97+
optionAlwaysAutoScroll: autoScroll ?? false,
98+
optionAlwaysExpandRunning: expandRunning ?? false,
7399
74100
// provided by backend
75101
run: {
@@ -147,6 +173,11 @@ const sfc = {
147173
},
148174
149175
methods: {
176+
saveLocaleStorageOptions() {
177+
const opts: LocaleStorageOptions = {autoScroll: this.optionAlwaysAutoScroll, expandRunning: this.optionAlwaysExpandRunning};
178+
localStorage.setItem('actions-view-options', JSON.stringify(opts));
179+
},
180+
150181
// get the job step logs container ('.job-step-logs')
151182
getJobStepLogsContainer(stepIndex: number): HTMLElement {
152183
return this.$refs.logs[stepIndex];
@@ -228,8 +259,10 @@ const sfc = {
228259
},
229260
230261
shouldAutoScroll(stepIndex: number): boolean {
262+
if (!this.optionAlwaysAutoScroll) return false;
231263
const el = this.getJobStepLogsContainer(stepIndex);
232-
if (!el.lastChild) return false;
264+
// if the logs container is empty, then auto-scroll if the step is expanded
265+
if (!el.lastChild) return this.currentJobStepsStates[stepIndex].expanded;
233266
return isLogElementInViewport(el.lastChild);
234267
},
235268
@@ -280,6 +313,7 @@ const sfc = {
280313
const abortController = new AbortController();
281314
this.loadingAbortController = abortController;
282315
try {
316+
const isFirstLoad = !this.run.status;
283317
const job = await this.fetchJobData(abortController);
284318
if (this.loadingAbortController !== abortController) return;
285319
@@ -289,9 +323,10 @@ const sfc = {
289323
290324
// sync the currentJobStepsStates to store the job step states
291325
for (let i = 0; i < this.currentJob.steps.length; i++) {
326+
const expanded = isFirstLoad && this.optionAlwaysExpandRunning && this.currentJob.steps[i].status === 'running';
292327
if (!this.currentJobStepsStates[i]) {
293328
// initial states for job steps
294-
this.currentJobStepsStates[i] = {cursor: null, expanded: false};
329+
this.currentJobStepsStates[i] = {cursor: null, expanded};
295330
}
296331
}
297332
@@ -426,6 +461,8 @@ export function initRepositoryActionView() {
426461
skipped: el.getAttribute('data-locale-status-skipped'),
427462
blocked: el.getAttribute('data-locale-status-blocked'),
428463
},
464+
logsAlwaysAutoScroll: el.getAttribute('data-locale-logs-always-auto-scroll'),
465+
logsAlwaysExpandRunning: el.getAttribute('data-locale-logs-always-expand-running'),
429466
},
430467
});
431468
view.mount(el);
@@ -528,6 +565,17 @@ export function initRepositoryActionView() {
528565
<i class="icon"><SvgIcon :name="isFullScreen ? 'octicon-check' : 'gitea-empty-checkbox'"/></i>
529566
{{ locale.showFullScreen }}
530567
</a>
568+
569+
<div class="divider"/>
570+
<a class="item" @click="optionAlwaysAutoScroll = !optionAlwaysAutoScroll">
571+
<i class="icon"><SvgIcon :name="optionAlwaysAutoScroll ? 'octicon-check' : 'gitea-empty-checkbox'"/></i>
572+
{{ locale.logsAlwaysAutoScroll }}
573+
</a>
574+
<a class="item" @click="optionAlwaysExpandRunning = !optionAlwaysExpandRunning">
575+
<i class="icon"><SvgIcon :name="optionAlwaysExpandRunning ? 'octicon-check' : 'gitea-empty-checkbox'"/></i>
576+
{{ locale.logsAlwaysExpandRunning }}
577+
</a>
578+
531579
<div class="divider"/>
532580
<a :class="['item', !currentJob.steps.length ? 'disabled' : '']" :href="run.link+'/jobs/'+jobIndex+'/logs'" target="_blank">
533581
<i class="icon"><SvgIcon name="octicon-download"/></i>

0 commit comments

Comments
 (0)