Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add show timestamp/seconds and fullscreen options to action page #24876

Merged
merged 68 commits into from
May 30, 2023
Merged
Show file tree
Hide file tree
Changes from 50 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
dea2476
test theme
HesterG May 10, 2023
ee2c2b7
save for test
HesterG May 16, 2023
1bf304c
save
HesterG May 17, 2023
d4352ad
save
HesterG May 17, 2023
91f2561
save
HesterG May 17, 2023
83c44d1
test timestamp
HesterG May 18, 2023
e1513b2
logmessage
HesterG May 18, 2023
7de4694
log
HesterG May 18, 2023
10bc9c4
save change
HesterG May 18, 2023
320c617
save
HesterG May 19, 2023
8562529
delete unrelated
HesterG May 22, 2023
758131a
remove
HesterG May 22, 2023
d7bfe88
save
HesterG May 23, 2023
d541184
add show fullscreen option
HesterG May 23, 2023
aeeec87
update icon
HesterG May 23, 2023
defd8c4
adjust colors
HesterG May 23, 2023
e9977ce
adjust timestamp
HesterG May 23, 2023
0929713
avoid shrink
HesterG May 23, 2023
1488624
add drone-like option
HesterG May 23, 2023
c2248bc
remove log
HesterG May 23, 2023
a6086d1
fix lint
HesterG May 23, 2023
f502186
comments
HesterG May 24, 2023
6f30916
fix lint
HesterG May 24, 2023
cd0b2b2
fix
HesterG May 24, 2023
f5236c7
Merge branch 'main' into add-timestamp
silverwind May 24, 2023
ec43e3f
Merge branch 'main' into add-timestamp
HesterG May 25, 2023
524275e
change timestamp and textcontent
HesterG May 25, 2023
cba5124
Merge branch 'main' into add-timestamp
HesterG May 25, 2023
24818a1
Merge branch 'go-gitea:main' into add-timestamp
HesterG May 25, 2023
ba2c6e8
use relative-time
HesterG May 25, 2023
0a4b3ab
revert
HesterG May 25, 2023
f68e122
revert
HesterG May 26, 2023
141ca0d
Merge branch 'main' into add-timestamp
HesterG May 26, 2023
5e66222
declare type and remove styles
HesterG May 26, 2023
b3a4ba0
add comments about why using native elements for log lines
wxiaoguang May 26, 2023
ea3c8a0
remove
HesterG May 26, 2023
000bd19
Merge branch 'main' into add-timestamp
HesterG May 26, 2023
95285b2
Merge branch 'main' into add-timestamp
HesterG May 29, 2023
3999800
Merge branch 'main' into add-timestamp
HesterG May 29, 2023
15dbbd8
use starttime from backend
HesterG May 29, 2023
47d38f1
rename variables and use if else
HesterG May 29, 2023
dfdc3ba
Merge branch 'main' into add-timestamp
HesterG May 29, 2023
629d14d
update toggleTimeDisplay
HesterG May 29, 2023
fd995e3
Merge branch 'main' into add-timestamp
HesterG May 29, 2023
3331de5
Update web_src/js/components/RepoActionView.vue
HesterG May 29, 2023
63065d5
Merge branch 'main' into add-timestamp
HesterG May 30, 2023
2ef5eba
fix lint
HesterG May 30, 2023
6a58dc0
rename duration to seconds
HesterG May 30, 2023
6d9a088
Merge branch 'main' into add-timestamp
HesterG May 30, 2023
9ab3ad9
Merge branch 'main' into add-timestamp
HesterG May 30, 2023
34c706f
color and padding tweaks
silverwind May 30, 2023
8d419e4
move locales, fix dropdown icons
silverwind May 30, 2023
2f64c8f
fullscreen fixes
silverwind May 30, 2023
26fd546
fix layout
silverwind May 30, 2023
4701ae0
fix selectors, add comment
silverwind May 30, 2023
334e2b3
add menu styles
silverwind May 30, 2023
809bdba
remove noop style
silverwind May 30, 2023
f3427c3
remove empty line
silverwind May 30, 2023
564e561
sort svg imports
silverwind May 30, 2023
a37e4ed
rename color to --color-console-fg-subtle
silverwind May 30, 2023
629b2c5
extend comment
silverwind May 30, 2023
d184fe2
use button-ghost
silverwind May 30, 2023
a3d7649
remove unneeded styles
silverwind May 30, 2023
3ff5417
use transparent colors again for hover/active
silverwind May 30, 2023
ac425cf
use opaque for active because it affects sticky header
silverwind May 30, 2023
bc61611
fix focus background
silverwind May 30, 2023
32c2112
add begin/end comments around override sections
silverwind May 30, 2023
35a03ef
Merge branch 'main' into add-timestamp
GiteaBot May 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3447,6 +3447,10 @@ runs.no_matching_runner_helper = No matching runner: %s

need_approval_desc = Need approval to run workflows for fork pull request.

options.show_timestamp = Show timestamps
options.show_full_screen = Show full screen
options.show_log_seconds = Show seconds

[projects]
type-1.display_name = Individual Project
type-2.display_name = Repository Project
Expand Down
3 changes: 3 additions & 0 deletions templates/repo/actions/view.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
data-locale-status-skipped="{{.locale.Tr "actions.status.skipped"}}"
data-locale-status-blocked="{{.locale.Tr "actions.status.blocked"}}"
data-locale-artifacts-title="{{$.locale.Tr "artifacts"}}"
data-locale-show-timestamp="{{.locale.Tr "actions.options.show_timestamp"}}"
data-locale-show-full-screen="{{.locale.Tr "actions.options.show_full_screen"}}"
data-locale-show-log-seconds="{{.locale.Tr "actions.options.show_log_seconds"}}"
>
</div>
</div>
Expand Down
154 changes: 136 additions & 18 deletions web_src/js/components/RepoActionView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,36 @@

<div class="action-view-right">
<div class="job-info-header">
<h3 class="job-info-header-title">
{{ currentJob.title }}
</h3>
<p class="job-info-header-detail">
{{ currentJob.detail }}
</p>
<div class="job-info-header-left">
<h3 class="job-info-header-title">
{{ currentJob.title }}
</h3>
<p class="job-info-header-detail">
{{ currentJob.detail }}
</p>
</div>
<div class="job-info-header-right">
<div class="ui top right pointing dropdown custom jump item" @click.stop="menuVisible = !menuVisible" @keyup.enter="menuVisible = !menuVisible">
<SvgIcon name="octicon-gear" :size="18"/>
<div class="menu transition action-job-menu" :class="{visible: menuVisible}" v-if="menuVisible" v-cloak>
<a class="item" @click="toggleTimeDisplay('seconds')">
<span><SvgIcon v-show="timeVisible['log-time-seconds']" name="octicon-check"/></span>
{{ locale.jobOptions.showLogSeconds }}
</a>
<a class="item" @click="toggleTimeDisplay('stamp')">
<span><SvgIcon v-show="timeVisible['log-time-stamp']" name="octicon-check"/></span>
{{ locale.jobOptions.showTimeStamp }}
</a>
<div class="divider"/>
<a class="item" @click="toggleFullScreen()">
<span><SvgIcon v-show="isFullScreen" name="octicon-check"/></span>
{{ locale.jobOptions.showFullScreen }}
</a>
</div>
</div>
</div>
</div>
<div class="job-step-container">
<div class="job-step-container" ref="steps">
<div class="job-step-section" v-for="(jobStep, i) in currentJob.steps" :key="i">
<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
Expand All @@ -81,7 +103,8 @@
<span class="step-summary-duration">{{ jobStep.duration }}</span>
</div>

<!-- the log elements could be a lot, do not use v-if to destroy/reconstruct the DOM -->
<!-- the log elements could be a lot, do not use v-if to destroy/reconstruct the DOM,
use native DOM elements for "log line" to improve performance, Vue is not suitable for managing so many reactive elements. -->
<div class="job-step-logs" ref="logs" v-show="currentJobStepsStates[i].expanded"/>
</div>
</div>
Expand All @@ -95,6 +118,8 @@ import {SvgIcon} from '../svg.js';
import ActionRunStatus from './ActionRunStatus.vue';
import {createApp} from 'vue';
import AnsiToHTML from 'ansi-to-html';
import {toggleElem} from '../utils/dom.js';
import {getCurrentLocale} from '../utils.js';

const {csrfToken} = window.config;

Expand All @@ -121,6 +146,12 @@ const sfc = {
currentJobStepsStates: [],
artifacts: [],
onHoverRerunIndex: -1,
menuVisible: false,
isFullScreen: false,
timeVisible: {
'log-time-stamp': false,
'log-time-seconds': false,
},

// provided by backend
run: {
Expand Down Expand Up @@ -173,6 +204,12 @@ const sfc = {
// load job data and then auto-reload periodically
this.loadJob();
this.intervalID = setInterval(this.loadJob, 1000);

document.body.addEventListener('click', this.closeDropdown);
},

beforeUnmount() {
document.body.removeEventListener('click', this.closeDropdown);
},

unmounted() {
Expand Down Expand Up @@ -240,7 +277,7 @@ const sfc = {
this.fetchPost(`${this.run.link}/approve`);
},

createLogLine(line) {
createLogLine(line, startTime) {
const div = document.createElement('div');
div.classList.add('job-log-line');
div._jobLogTime = line.timestamp;
Expand All @@ -250,21 +287,35 @@ const sfc = {
lineNumber.textContent = line.index;
div.append(lineNumber);

// TODO: Support displaying time optionally

const logMessage = document.createElement('div');
// for "Show timestamps"
const logTimeStamp = document.createElement('span');
logTimeStamp.className = 'log-time-stamp';
const date = new Date(parseFloat(line.timestamp * 1000));
const timeStamp = date.toLocaleString(getCurrentLocale(), {timeZoneName: 'short'});
logTimeStamp.textContent = timeStamp;
toggleElem(logTimeStamp, this.timeVisible['log-time-stamp']);
// for "Show seconds"
const logTimeSeconds = document.createElement('span');
logTimeSeconds.className = 'log-time-seconds';
const seconds = Math.floor(parseFloat(line.timestamp) - parseFloat(startTime));
logTimeSeconds.textContent = `${seconds}s`;
toggleElem(logTimeSeconds, this.timeVisible['log-time-seconds']);

const logMessage = document.createElement('span');
logMessage.className = 'log-msg';
logMessage.innerHTML = ansiLogToHTML(line.message);
div.append(logTimeStamp);
div.append(logMessage);
div.append(logTimeSeconds);

return div;
},

appendLogs(stepIndex, logLines) {
appendLogs(stepIndex, logLines, startTime) {
for (const line of logLines) {
// TODO: group support: ##[group]GroupTitle , ##[endgroup]
const el = this.getLogsContainer(stepIndex);
el.append(this.createLogLine(line));
el.append(this.createLogLine(line, startTime));
HesterG marked this conversation as resolved.
Show resolved Hide resolved
}
},

Expand Down Expand Up @@ -309,7 +360,7 @@ const sfc = {
for (const logs of response.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.lines);
this.appendLogs(logs.step, logs.lines, logs.started);
}

if (this.run.done && this.intervalID) {
Expand All @@ -335,6 +386,46 @@ const sfc = {

isDone(status) {
return ['success', 'skipped', 'failure', 'cancelled'].includes(status);
},

closeDropdown() {
if (this.menuVisible) this.menuVisible = false;
},

// show at most one of log seconds and timestamp (can be both invisible)
toggleTimeDisplay(type) {
const toToggleTypes = [];
const other = type === 'seconds' ? 'stamp' : 'seconds';
this.timeVisible[`log-time-${type}`] = !this.timeVisible[`log-time-${type}`];
toToggleTypes.push(type);
if (this.timeVisible[`log-time-${type}`] && this.timeVisible[`log-time-${other}`]) {
this.timeVisible[`log-time-${other}`] = false;
toToggleTypes.push(other);
}
for (const toToggle of toToggleTypes) {
for (const el of this.$refs.steps.querySelectorAll(`.log-time-${toToggle}`)) {
toggleElem(el, this.timeVisible[`log-time-${toToggle}`]);
}
}
},

toggleFullScreen() {
this.isFullScreen = !this.isFullScreen;
const fullScreenEl = document.querySelector('.action-view-right');
const outerEl = document.querySelector('.full.height');
const actionBodyEl = document.querySelector('.action-view-body');
const headerEl = document.querySelector('.ui.main.menu');
const contentEl = document.querySelector('.page-content.repository');
const footerEl = document.querySelector('.page-footer');
toggleElem(headerEl, !this.isFullScreen);
toggleElem(contentEl, !this.isFullScreen);
toggleElem(footerEl, !this.isFullScreen);
// move .action-view-right to new parent
if (this.isFullScreen) {
outerEl.append(fullScreenEl);
} else {
actionBodyEl.append(fullScreenEl);
}
}
},
};
Expand Down Expand Up @@ -369,7 +460,12 @@ export function initRepositoryActionView() {
cancelled: el.getAttribute('data-locale-status-cancelled'),
skipped: el.getAttribute('data-locale-status-skipped'),
blocked: el.getAttribute('data-locale-status-blocked'),
}
},
jobOptions: {
showTimeStamp: el.getAttribute('data-locale-show-timestamp'),
showFullScreen: el.getAttribute('data-locale-show-full-screen'),
showLogSeconds: el.getAttribute('data-locale-show-log-seconds'),
},
}
});
view.mount(el);
Expand Down Expand Up @@ -574,14 +670,28 @@ export function ansiLogToHTML(line) {
flex-direction: column;
}

.full.height > .action-view-right {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this take affect? It is in scoped.

Copy link
Contributor Author

@HesterG HesterG May 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good point. It is actually working.. Otherwise, show fullscreen will not have any effect.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But how could it work? It's out of my knowledge.

IIRC, after Vue compiler's processing, the style selector becomes .full.height[data-xxx] > ... ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I remembered the same thing..

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screen Shot 2023-05-30 at 09 02 46

I see, it is because full height is not compiled by Vue, only action-view-right is.

width: 100%;
height: 100%;
padding: 0;
}

.full.height > .action-view-right > .job-step-container {
height: 100%;
}

.job-info-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
border-bottom: 1px solid var(--color-console-border);
background-color: var(--color-console-bg);
position: sticky;
top: 0;
border-radius: var(--border-radius) var(--border-radius) 0 0;
height: 60px;
z-index: 1;
}

.job-info-header .job-info-header-title {
Expand All @@ -595,6 +705,12 @@ export function ansiLogToHTML(line) {
font-size: 12px;
}

.action-job-menu .item span {
display: inline-block;
height: 16px;
width: 16px;
}

silverwind marked this conversation as resolved.
Show resolved Hide resolved
.job-step-container {
background-color: var(--color-console-bg);
max-height: 100%;
Expand Down Expand Up @@ -676,14 +792,16 @@ export function ansiLogToHTML(line) {
background-color: var(--color-console-hover-bg);
}

.job-step-section .job-step-logs .job-log-line .line-num {
/* 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;
color: var(--color-grey-light);
text-align: right;
user-select: none;
}

.job-step-section .job-step-logs .job-log-line .log-time {
.job-log-line .log-time,
.log-time-stamp {
color: var(--color-grey-light);
margin-left: 10px;
white-space: nowrap;
Expand Down
4 changes: 3 additions & 1 deletion web_src/js/svg.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ import octiconTag from '../../public/img/svg/octicon-tag.svg';
import octiconTriangleDown from '../../public/img/svg/octicon-triangle-down.svg';
import octiconX from '../../public/img/svg/octicon-x.svg';
import octiconXCircleFill from '../../public/img/svg/octicon-x-circle-fill.svg';
import octiconGear from '../../public/img/svg/octicon-gear.svg';

const svgs = {
'gitea-double-chevron-left': giteaDoubleChevronLeft,
Expand Down Expand Up @@ -132,7 +133,8 @@ const svgs = {
'octicon-tag': octiconTag,
'octicon-triangle-down': octiconTriangleDown,
'octicon-x': octiconX,
'octicon-x-circle-fill': octiconXCircleFill
'octicon-x-circle-fill': octiconXCircleFill,
'octicon-gear': octiconGear,
};

// TODO: use a more general approach to access SVG icons.
Expand Down
2 changes: 1 addition & 1 deletion web_src/js/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export function parseUrl(str) {
}

// return current locale chosen by user
function getCurrentLocale() {
export function getCurrentLocale() {
return document.documentElement.lang;
}

Expand Down