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.

216 lines
6 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';
import { scrollToElement } 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'),
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-13 15:12:31 +05:30
jobLog: {
type: Array,
required: true,
},
},
data() {
return {
searchTerm: '',
searchResults: [],
};
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-13 15:12:31 +05:30
showJobLogSearch() {
return this.glFeatures.jobLogSearch;
},
2018-12-13 13:39:08 +05:30
},
methods: {
handleScrollToTop() {
this.$emit('scrollJobLogTop');
},
handleScrollToBottom() {
this.$emit('scrollJobLogBottom');
},
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>
2018-12-13 13:39:08 +05:30
<div class="top-bar">
2018-11-20 20:47:30 +05:30
<!-- truncate information -->
2021-06-08 01:23:25 +05:30
<div
class="truncated-info gl-display-none gl-sm-display-block gl-float-left"
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 -->
2021-06-08 01:23:25 +05:30
<div class="controllers gl-float-right">
2022-08-13 15:12:31 +05:30
<template v-if="showJobLogSearch">
<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"
/>
<help-popover class="gl-mr-3">
<template #title>{{ $options.i18n.searchPopoverTitle }}</template>
<p class="gl-mb-0">
{{ $options.i18n.searchPopoverDescription }}
</p>
</help-popover>
</template>
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 -->
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>