Skip to content

Commit

Permalink
Add action auto-scroll (#30057)
Browse files Browse the repository at this point in the history
Adds an auto-scroll/follow feature to running actions (fix #25186, fix
#28535).

When new log lines are appended and the bottom of the logs container
(`.action-view-right`) is visible at this time, the page automatically
scrolls down to the bottom of the logs.

---------

Co-authored-by: silverwind <[email protected]>
Co-authored-by: wxiaoguang <[email protected]>
  • Loading branch information
3 people authored Dec 21, 2024
1 parent 1439468 commit 5d6d624
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 6 deletions.
4 changes: 2 additions & 2 deletions web_src/js/components/ActionRunStatus.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import {SvgIcon} from '../svg.ts';

withDefaults(defineProps<{
status: 'success' | 'skipped' | 'waiting' | 'blocked' | 'running' | 'failure' | 'cancelled' | 'unknown',
size: number,
className: string,
size?: number,
className?: string,
localeStatus?: string,
}>(), {
size: 16,
Expand Down
41 changes: 37 additions & 4 deletions web_src/js/components/RepoActionView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ function parseLineCommand(line: LogLine): LogLineCommand | null {
return null;
}
function isLogElementInViewport(el: HTMLElement): boolean {
const rect = el.getBoundingClientRect();
return rect.top >= 0 && rect.bottom <= window.innerHeight; // only check height but not width
}
const sfc = {
name: 'RepoActionView',
components: {
Expand Down Expand Up @@ -142,9 +147,14 @@ const sfc = {
},
methods: {
// get the active container element, either the `job-step-logs` or the `job-log-list` in the `job-log-group`
getLogsContainer(stepIndex: number) {
const el = this.$refs.logs[stepIndex];
// get the job step logs container ('.job-step-logs')
getJobStepLogsContainer(stepIndex: number): HTMLElement {
return this.$refs.logs[stepIndex];
},
// get the active logs container element, either the `job-step-logs` or the `job-log-list` in the `job-log-group`
getActiveLogsContainer(stepIndex: number): HTMLElement {
const el = this.getJobStepLogsContainer(stepIndex);
return el._stepLogsActiveContainer ?? el;
},
// begin a log group
Expand Down Expand Up @@ -217,9 +227,15 @@ const sfc = {
);
},
shouldAutoScroll(stepIndex: number): boolean {
const el = this.getJobStepLogsContainer(stepIndex);
if (!el.lastChild) return false;
return isLogElementInViewport(el.lastChild);
},
appendLogs(stepIndex: number, startTime: number, logLines: LogLine[]) {
for (const line of logLines) {
const el = this.getLogsContainer(stepIndex);
const el = this.getActiveLogsContainer(stepIndex);
const cmd = parseLineCommand(line);
if (cmd?.name === 'group') {
this.beginLogGroup(stepIndex, startTime, line, cmd);
Expand Down Expand Up @@ -278,13 +294,30 @@ const sfc = {
this.currentJobStepsStates[i] = {cursor: null, expanded: false};
}
}
// find the step indexes that need to auto-scroll
const autoScrollStepIndexes = new Map<number, boolean>();
for (const logs of job.logs.stepsLog ?? []) {
if (autoScrollStepIndexes.has(logs.step)) continue;
autoScrollStepIndexes.set(logs.step, this.shouldAutoScroll(logs.step));
}
// append logs to the UI
for (const logs of job.logs.stepsLog ?? []) {
// save the cursor, it will be passed to backend next time
this.currentJobStepsStates[logs.step].cursor = logs.cursor;
this.appendLogs(logs.step, logs.started, logs.lines);
}
// auto-scroll to the last log line of the last step
let autoScrollJobStepElement: HTMLElement;
for (let stepIndex = 0; stepIndex < this.currentJob.steps.length; stepIndex++) {
if (!autoScrollStepIndexes.get(stepIndex)) continue;
autoScrollJobStepElement = this.getJobStepLogsContainer(stepIndex);
}
autoScrollJobStepElement?.lastElementChild.scrollIntoView({behavior: 'smooth', block: 'nearest'});
// clear the interval timer if the job is done
if (this.run.done && this.intervalID) {
clearInterval(this.intervalID);
this.intervalID = null;
Expand Down

0 comments on commit 5d6d624

Please sign in to comment.