|
|
@@ -204,15 +204,19 @@ const sfc = { |
|
|
|
}; |
|
|
|
}, |
|
|
|
|
|
|
|
mounted() { |
|
|
|
async mounted() { |
|
|
|
// load job data and then auto-reload periodically |
|
|
|
this.loadJob(); |
|
|
|
// need to await first loadJob so this.currentJobStepsStates is initialized and can be used in hashChangeListener |
|
|
|
await this.loadJob(); |
|
|
|
this.intervalID = setInterval(this.loadJob, 1000); |
|
|
|
document.body.addEventListener('click', this.closeDropdown); |
|
|
|
this.hashChangeListener(); |
|
|
|
window.addEventListener('hashchange', this.hashChangeListener); |
|
|
|
}, |
|
|
|
|
|
|
|
beforeUnmount() { |
|
|
|
document.body.removeEventListener('click', this.closeDropdown); |
|
|
|
window.removeEventListener('hashchange', this.hashChangeListener); |
|
|
|
}, |
|
|
|
|
|
|
|
unmounted() { |
|
|
@@ -280,14 +284,16 @@ const sfc = { |
|
|
|
this.fetchPost(`${this.run.link}/approve`); |
|
|
|
}, |
|
|
|
|
|
|
|
createLogLine(line, startTime) { |
|
|
|
createLogLine(line, startTime, stepIndex) { |
|
|
|
const div = document.createElement('div'); |
|
|
|
div.classList.add('job-log-line'); |
|
|
|
div.setAttribute('id', `jobstep-${stepIndex}-${line.index}`); |
|
|
|
div._jobLogTime = line.timestamp; |
|
|
|
|
|
|
|
const lineNumber = document.createElement('div'); |
|
|
|
lineNumber.className = 'line-num'; |
|
|
|
const lineNumber = document.createElement('a'); |
|
|
|
lineNumber.classList.add('line-num', 'muted'); |
|
|
|
lineNumber.textContent = line.index; |
|
|
|
lineNumber.setAttribute('href', `#jobstep-${stepIndex}-${line.index}`); |
|
|
|
div.append(lineNumber); |
|
|
|
|
|
|
|
// for "Show timestamps" |
|
|
@@ -318,7 +324,7 @@ const sfc = { |
|
|
|
for (const line of logLines) { |
|
|
|
// TODO: group support: ##[group]GroupTitle , ##[endgroup] |
|
|
|
const el = this.getLogsContainer(stepIndex); |
|
|
|
el.append(this.createLogLine(line, startTime)); |
|
|
|
el.append(this.createLogLine(line, startTime, stepIndex)); |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
@@ -429,6 +435,21 @@ const sfc = { |
|
|
|
} else { |
|
|
|
actionBodyEl.append(fullScreenEl); |
|
|
|
} |
|
|
|
}, |
|
|
|
async hashChangeListener() { |
|
|
|
const selectedLogStep = window.location.hash; |
|
|
|
if (!selectedLogStep) return; |
|
|
|
const [_, step, _line] = selectedLogStep.split('-'); |
|
|
|
if (!this.currentJobStepsStates[step]) return; |
|
|
|
if (!this.currentJobStepsStates[step].expanded && this.currentJobStepsStates[step].cursor === null) { |
|
|
|
this.currentJobStepsStates[step].expanded = true; |
|
|
|
// need to await for load job if the step log is loaded for the first time |
|
|
|
// so logline can be selected by querySelector |
|
|
|
await this.loadJob(); |
|
|
|
} |
|
|
|
const logLine = this.$refs.steps.querySelector(selectedLogStep); |
|
|
|
if (!logLine) return; |
|
|
|
logLine.querySelector('.line-num').click(); |
|
|
|
} |
|
|
|
}, |
|
|
|
}; |
|
|
@@ -802,10 +823,15 @@ export function initRepositoryActionView() { |
|
|
|
display: flex; |
|
|
|
} |
|
|
|
|
|
|
|
.job-step-section .job-step-logs .job-log-line:hover { |
|
|
|
.job-log-line:hover, |
|
|
|
.job-log-line:target { |
|
|
|
background-color: var(--color-console-hover-bg); |
|
|
|
} |
|
|
|
|
|
|
|
.job-log-line:target { |
|
|
|
scroll-margin-top: 95px; |
|
|
|
} |
|
|
|
|
|
|
|
/* class names 'log-time-seconds' and 'log-time-stamp' are used in the method toggleTimeDisplay */ |
|
|
|
.job-log-line .line-num, .log-time-seconds { |
|
|
|
width: 48px; |
|
|
@@ -814,6 +840,11 @@ export function initRepositoryActionView() { |
|
|
|
user-select: none; |
|
|
|
} |
|
|
|
|
|
|
|
.job-log-line:target > .line-num { |
|
|
|
color: var(--color-primary); |
|
|
|
text-decoration: underline; |
|
|
|
} |
|
|
|
|
|
|
|
.log-time-seconds { |
|
|
|
padding-right: 2px; |
|
|
|
} |