debian-mirror-gitlab/app/assets/javascripts/jobs/components/job_log_controllers.vue

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

266 lines
7.5 KiB
Vue
Raw Normal View History

2018-11-20 20:47:30 +05:30
<script>
2022-08-13 15:12:31 +05:30
import { GlTooltipDirective, GlLink, GlButton, GlSearchBoxByClick } from '@gitlab/ui';
2022-08-27 11:52:29 +05:30
import { scrollToElement, backOff } from '~/lib/utils/common_utils';
2018-12-13 13:39:08 +05:30
import { numberToHumanSize } from '~/lib/utils/number_utils';
2021-04-29 21:17:54 +05:30
import { __, s__, sprintf } from '~/locale';
2022-08-13 15:12:31 +05:30
import HelpPopover from '~/vue_shared/components/help_popover.vue';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
2018-11-20 20:47:30 +05:30
2018-12-13 13:39:08 +05:30
export default {
2021-04-29 21:17:54 +05:30
i18n: {
scrollToBottomButtonLabel: s__('Job|Scroll to bottom'),
scrollToTopButtonLabel: s__('Job|Scroll to top'),
2022-08-27 11:52:29 +05:30
scrollToNextFailureButtonLabel: s__('Job|Scroll to next failure'),
2021-04-29 21:17:54 +05:30
showRawButtonLabel: s__('Job|Show complete raw'),
2022-08-13 15:12:31 +05:30
searchPlaceholder: s__('Job|Search job log'),
noResults: s__('Job|No search results found'),
searchPopoverTitle: s__('Job|Job log search'),
searchPopoverDescription: s__(
'Job|Search for substrings in your job log output. Currently search is only supported for the visible job log output, not for any log output that is truncated due to size.',
),
logLineNumberNotFound: s__('Job|We could not find this element'),
2021-04-29 21:17:54 +05:30
},
2018-12-13 13:39:08 +05:30
components: {
GlLink,
2020-11-24 15:15:51 +05:30
GlButton,
2022-08-13 15:12:31 +05:30
GlSearchBoxByClick,
HelpPopover,
2018-12-13 13:39:08 +05:30
},
directives: {
GlTooltip: GlTooltipDirective,
},
2022-08-13 15:12:31 +05:30
mixins: [glFeatureFlagMixin()],
2018-12-13 13:39:08 +05:30
props: {
size: {
type: Number,
required: true,
2018-11-20 20:47:30 +05:30
},
2018-12-13 13:39:08 +05:30
rawPath: {
type: String,
required: false,
default: null,
2018-11-20 20:47:30 +05:30
},
2018-12-13 13:39:08 +05:30
isScrollTopDisabled: {
type: Boolean,
required: true,
2018-11-20 20:47:30 +05:30
},
2018-12-13 13:39:08 +05:30
isScrollBottomDisabled: {
type: Boolean,
required: true,
2018-12-05 23:21:45 +05:30
},
2018-12-13 13:39:08 +05:30
isScrollingDown: {
type: Boolean,
required: true,
2018-11-20 20:47:30 +05:30
},
2021-11-18 22:05:49 +05:30
isJobLogSizeVisible: {
2018-12-13 13:39:08 +05:30
type: Boolean,
required: true,
},
2022-08-27 11:52:29 +05:30
isComplete: {
type: Boolean,
required: true,
},
2022-08-13 15:12:31 +05:30
jobLog: {
type: Array,
required: true,
},
},
data() {
return {
searchTerm: '',
searchResults: [],
2022-08-27 11:52:29 +05:30
failureCount: null,
failureIndex: 0,
2022-08-13 15:12:31 +05:30
};
2018-12-13 13:39:08 +05:30
},
computed: {
jobLogSize() {
2019-09-30 21:07:59 +05:30
return sprintf(__('Showing last %{size} of log -'), {
2018-12-13 13:39:08 +05:30
size: numberToHumanSize(this.size),
});
},
2022-08-27 11:52:29 +05:30
showJumpToFailures() {
return this.glFeatures.jobLogJumpToFailures;
},
hasFailures() {
return this.failureCount > 0;
},
shouldDisableJumpToFailures() {
return !this.hasFailures;
2022-08-13 15:12:31 +05:30
},
2018-12-13 13:39:08 +05:30
},
2022-08-27 11:52:29 +05:30
mounted() {
this.checkFailureCount();
},
2018-12-13 13:39:08 +05:30
methods: {
2022-08-27 11:52:29 +05:30
checkFailureCount() {
if (this.glFeatures.jobLogJumpToFailures) {
backOff((next, stop) => {
this.failureCount = document.querySelectorAll('.term-fg-l-red').length;
if (this.hasFailures || (this.isComplete && !this.hasFailures)) {
stop();
} else {
next();
}
});
}
},
handleScrollToNextFailure() {
const failures = document.querySelectorAll('.term-fg-l-red');
const nextFailure = failures[this.failureIndex];
if (nextFailure) {
nextFailure.scrollIntoView({ block: 'center' });
this.failureIndex = (this.failureIndex + 1) % failures.length;
}
},
2018-12-13 13:39:08 +05:30
handleScrollToTop() {
this.$emit('scrollJobLogTop');
2022-08-27 11:52:29 +05:30
this.failureIndex = 0;
2018-12-13 13:39:08 +05:30
},
handleScrollToBottom() {
this.$emit('scrollJobLogBottom');
2022-08-27 11:52:29 +05:30
this.failureIndex = 0;
2018-12-13 13:39:08 +05:30
},
2022-08-13 15:12:31 +05:30
searchJobLog() {
this.searchResults = [];
if (!this.searchTerm) return;
const compactedLog = [];
this.jobLog.forEach((obj) => {
if (obj.lines && obj.lines.length > 0) {
compactedLog.push(...obj.lines);
}
if (!obj.lines && obj.content.length > 0) {
compactedLog.push(obj);
}
});
compactedLog.forEach((line) => {
const lineText = line.content[0].text;
if (lineText.toLocaleLowerCase().includes(this.searchTerm.toLocaleLowerCase())) {
this.searchResults.push(line);
}
});
if (this.searchResults.length > 0) {
this.$emit('searchResults', this.searchResults);
// BE returns zero based index, we need to add one to match the line numbers in the DOM
const firstSearchResult = `#L${this.searchResults[0].lineNumber + 1}`;
const logLine = document.querySelector(`.js-line ${firstSearchResult}`);
if (logLine) {
setTimeout(() => scrollToElement(logLine));
const message = sprintf(s__('Job|%{searchLength} results found for %{searchTerm}'), {
searchLength: this.searchResults.length,
searchTerm: this.searchTerm,
});
this.$toast.show(message);
} else {
this.$toast.show(this.$options.i18n.logLineNumberNotFound);
}
} else {
this.$toast.show(this.$options.i18n.noResults);
}
},
2018-12-13 13:39:08 +05:30
},
};
2018-11-20 20:47:30 +05:30
</script>
<template>
2022-08-27 11:52:29 +05:30
<div class="top-bar gl-display-flex gl-justify-content-space-between">
2018-11-20 20:47:30 +05:30
<!-- truncate information -->
2021-06-08 01:23:25 +05:30
<div
2022-08-27 11:52:29 +05:30
class="truncated-info gl-display-none gl-sm-display-flex gl-flex-wrap gl-align-items-center"
2021-06-08 01:23:25 +05:30
data-testid="log-truncated-info"
>
2021-11-18 22:05:49 +05:30
<template v-if="isJobLogSizeVisible">
2018-12-05 23:21:45 +05:30
{{ jobLogSize }}
2019-07-31 22:56:46 +05:30
<gl-link
v-if="rawPath"
:href="rawPath"
2020-10-24 23:57:45 +05:30
class="text-plain text-underline gl-ml-2"
data-testid="raw-link"
2019-09-30 21:07:59 +05:30
>{{ s__('Job|Complete Raw') }}</gl-link
2019-07-31 22:56:46 +05:30
>
2018-12-05 23:21:45 +05:30
</template>
2018-11-20 20:47:30 +05:30
</div>
<!-- eo truncate information -->
2022-08-27 11:52:29 +05:30
<div class="controllers">
<gl-search-box-by-click
v-model="searchTerm"
class="gl-mr-3"
:placeholder="$options.i18n.searchPlaceholder"
data-testid="job-log-search-box"
@clear="$emit('searchResults', [])"
@submit="searchJobLog"
/>
2022-08-13 15:12:31 +05:30
2022-08-27 11:52:29 +05:30
<help-popover class="gl-mr-3">
<template #title>{{ $options.i18n.searchPopoverTitle }}</template>
2022-08-13 15:12:31 +05:30
2022-08-27 11:52:29 +05:30
<p class="gl-mb-0">
{{ $options.i18n.searchPopoverDescription }}
</p>
</help-popover>
2022-08-13 15:12:31 +05:30
2018-11-20 20:47:30 +05:30
<!-- links -->
2020-11-24 15:15:51 +05:30
<gl-button
2018-12-05 23:21:45 +05:30
v-if="rawPath"
2018-12-13 13:39:08 +05:30
v-gl-tooltip.body
2021-04-29 21:17:54 +05:30
:title="$options.i18n.showRawButtonLabel"
:aria-label="$options.i18n.showRawButtonLabel"
2018-12-05 23:21:45 +05:30
:href="rawPath"
2020-10-24 23:57:45 +05:30
data-testid="job-raw-link-controller"
2020-11-24 15:15:51 +05:30
icon="doc-text"
/>
2018-11-20 20:47:30 +05:30
<!-- eo links -->
<!-- scroll buttons -->
2022-08-27 11:52:29 +05:30
<gl-button
v-if="showJumpToFailures"
v-gl-tooltip
:title="$options.i18n.scrollToNextFailureButtonLabel"
:aria-label="$options.i18n.scrollToNextFailureButtonLabel"
:disabled="shouldDisableJumpToFailures"
class="btn-scroll gl-ml-3"
data-testid="job-controller-scroll-to-failure"
icon="soft-wrap"
@click="handleScrollToNextFailure"
/>
2021-04-29 21:17:54 +05:30
<div v-gl-tooltip :title="$options.i18n.scrollToTopButtonLabel" class="gl-ml-3">
2020-11-24 15:15:51 +05:30
<gl-button
2018-12-05 23:21:45 +05:30
:disabled="isScrollTopDisabled"
2021-04-17 20:07:23 +05:30
class="btn-scroll"
2020-10-24 23:57:45 +05:30
data-testid="job-controller-scroll-top"
2020-11-24 15:15:51 +05:30
icon="scroll_up"
2021-04-29 21:17:54 +05:30
:aria-label="$options.i18n.scrollToTopButtonLabel"
2018-11-20 20:47:30 +05:30
@click="handleScrollToTop"
2020-11-24 15:15:51 +05:30
/>
2018-11-20 20:47:30 +05:30
</div>
2021-04-29 21:17:54 +05:30
<div v-gl-tooltip :title="$options.i18n.scrollToBottomButtonLabel" class="gl-ml-3">
2020-11-24 15:15:51 +05:30
<gl-button
2018-12-05 23:21:45 +05:30
:disabled="isScrollBottomDisabled"
2021-04-17 20:07:23 +05:30
class="js-scroll-bottom btn-scroll"
2020-10-24 23:57:45 +05:30
data-testid="job-controller-scroll-bottom"
2020-11-24 15:15:51 +05:30
icon="scroll_down"
:class="{ animate: isScrollingDown }"
2021-04-29 21:17:54 +05:30
:aria-label="$options.i18n.scrollToBottomButtonLabel"
2018-11-20 20:47:30 +05:30
@click="handleScrollToBottom"
2018-12-13 13:39:08 +05:30
/>
2018-11-20 20:47:30 +05:30
</div>
<!-- eo scroll buttons -->
</div>
</div>
</template>