Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-09-20 14:18:08 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-09-20 14:18:08 +0300
commit5afcbe03ead9ada87621888a31a62652b10a7e4f (patch)
tree9918b67a0d0f0bafa6542e839a8be37adf73102d /app/assets/javascripts/ci/job_details/components/log/log.vue
parentc97c0201564848c1f53226fe19d71fdcc472f7d0 (diff)
Add latest changes from gitlab-org/gitlab@16-4-stable-eev16.4.0-rc42
Diffstat (limited to 'app/assets/javascripts/ci/job_details/components/log/log.vue')
-rw-r--r--app/assets/javascripts/ci/job_details/components/log/log.vue106
1 files changed, 106 insertions, 0 deletions
diff --git a/app/assets/javascripts/ci/job_details/components/log/log.vue b/app/assets/javascripts/ci/job_details/components/log/log.vue
new file mode 100644
index 00000000000..fb6a6a58074
--- /dev/null
+++ b/app/assets/javascripts/ci/job_details/components/log/log.vue
@@ -0,0 +1,106 @@
+<!-- eslint-disable vue/multi-word-component-names -->
+<script>
+// eslint-disable-next-line no-restricted-imports
+import { mapState, mapActions } from 'vuex';
+import { scrollToElement } from '~/lib/utils/common_utils';
+import { getLocationHash } from '~/lib/utils/url_utility';
+import CollapsibleLogSection from './collapsible_section.vue';
+import LogLine from './line.vue';
+
+export default {
+ components: {
+ CollapsibleLogSection,
+ LogLine,
+ },
+ props: {
+ searchResults: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
+ },
+ computed: {
+ ...mapState([
+ 'jobLogEndpoint',
+ 'jobLog',
+ 'isJobLogComplete',
+ 'isScrolledToBottomBeforeReceivingJobLog',
+ ]),
+ highlightedLines() {
+ return this.searchResults.map((result) => result.lineNumber);
+ },
+ },
+ updated() {
+ this.$nextTick(() => {
+ if (!window.location.hash) {
+ this.handleScrollDown();
+ }
+ });
+ },
+ mounted() {
+ if (window.location.hash) {
+ const lineNumber = getLocationHash();
+
+ this.unwatchJobLog = this.$watch('jobLog', async () => {
+ if (this.jobLog.length) {
+ await this.$nextTick();
+
+ const el = document.getElementById(lineNumber);
+ scrollToElement(el);
+ this.unwatchJobLog();
+ }
+ });
+ }
+ },
+ methods: {
+ ...mapActions(['toggleCollapsibleLine', 'scrollBottom']),
+ handleOnClickCollapsibleLine(section) {
+ this.toggleCollapsibleLine(section);
+ },
+ /**
+ * The job log is sent in HTML, which means we need to use `v-html` to render it
+ * Using the updated hook with $nextTick is not enough to wait for the DOM to be updated
+ * in this case because it runs before `v-html` has finished running, since there's no
+ * Vue binding.
+ * In order to scroll the page down after `v-html` has finished, we need to use setTimeout
+ */
+ handleScrollDown() {
+ if (this.isScrolledToBottomBeforeReceivingJobLog) {
+ setTimeout(() => {
+ this.scrollBottom();
+ }, 0);
+ }
+ },
+ isHighlighted({ lineNumber }) {
+ return this.highlightedLines.includes(lineNumber);
+ },
+ },
+};
+</script>
+<template>
+ <code class="job-log d-block" data-testid="job-log-content">
+ <template v-for="(section, index) in jobLog">
+ <collapsible-log-section
+ v-if="section.isHeader"
+ :key="`collapsible-${index}`"
+ :section="section"
+ :job-log-endpoint="jobLogEndpoint"
+ :search-results="searchResults"
+ @onClickCollapsibleLine="handleOnClickCollapsibleLine"
+ />
+ <log-line
+ v-else
+ :key="section.offset"
+ :line="section"
+ :path="jobLogEndpoint"
+ :is-highlighted="isHighlighted(section)"
+ />
+ </template>
+
+ <div v-if="!isJobLogComplete" class="js-log-animation loader-animation pt-3 pl-3">
+ <div class="dot"></div>
+ <div class="dot"></div>
+ <div class="dot"></div>
+ </div>
+ </code>
+</template>