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

333 lines
9.3 KiB
Vue
Raw Normal View History

2018-12-05 23:21:45 +05:30
<script>
2021-02-22 17:27:13 +05:30
import { GlLoadingIcon, GlIcon, GlSafeHtmlDirective as SafeHtml, GlAlert } from '@gitlab/ui';
2020-03-13 15:44:24 +05:30
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
2021-03-11 19:13:27 +05:30
import { throttle, isEmpty } from 'lodash';
import { mapGetters, mapState, mapActions } from 'vuex';
2021-06-08 01:23:25 +05:30
import CodeQualityWalkthrough from '~/code_quality_walkthrough/components/step.vue';
2018-12-13 13:39:08 +05:30
import { isScrolledToBottom } from '~/lib/utils/scroll_utils';
2021-11-11 11:23:49 +05:30
import { __, sprintf } from '~/locale';
2018-12-13 13:39:08 +05:30
import CiHeader from '~/vue_shared/components/header_ci_component.vue';
2021-03-11 19:13:27 +05:30
import delayedJobMixin from '../mixins/delayed_job_mixin';
2018-12-13 13:39:08 +05:30
import EmptyState from './empty_state.vue';
import EnvironmentsBlock from './environments_block.vue';
import ErasedBlock from './erased_block.vue';
import LogTopBar from './job_log_controllers.vue';
2021-03-11 19:13:27 +05:30
import Log from './log/log.vue';
import Sidebar from './sidebar.vue';
2018-12-13 13:39:08 +05:30
import StuckBlock from './stuck_block.vue';
2019-07-07 11:18:12 +05:30
import UnmetPrerequisitesBlock from './unmet_prerequisites_block.vue';
2018-12-13 13:39:08 +05:30
export default {
name: 'JobPageApp',
components: {
CiHeader,
EmptyState,
EnvironmentsBlock,
ErasedBlock,
2020-11-24 15:15:51 +05:30
GlIcon,
2020-07-28 23:09:34 +05:30
Log,
2018-12-13 13:39:08 +05:30
LogTopBar,
StuckBlock,
2019-07-07 11:18:12 +05:30
UnmetPrerequisitesBlock,
2018-12-13 13:39:08 +05:30
Sidebar,
GlLoadingIcon,
2019-07-07 11:18:12 +05:30
SharedRunner: () => import('ee_component/jobs/components/shared_runner_limit_block.vue'),
2021-02-22 17:27:13 +05:30
GlAlert,
2021-06-08 01:23:25 +05:30
CodeQualityWalkthrough,
2018-12-13 13:39:08 +05:30
},
2020-11-05 12:06:23 +05:30
directives: {
SafeHtml,
},
2018-12-13 13:39:08 +05:30
mixins: [delayedJobMixin],
props: {
2020-11-24 15:15:51 +05:30
artifactHelpUrl: {
type: String,
required: false,
default: '',
},
2018-12-13 13:39:08 +05:30
runnerSettingsUrl: {
type: String,
required: false,
default: null,
},
2019-07-07 11:18:12 +05:30
deploymentHelpUrl: {
type: String,
required: false,
default: null,
},
2018-12-13 13:39:08 +05:30
terminalPath: {
type: String,
required: false,
default: null,
},
2019-10-12 21:52:04 +05:30
projectPath: {
type: String,
required: true,
},
2019-12-04 20:38:33 +05:30
subscriptionsMoreMinutesUrl: {
type: String,
required: false,
default: null,
},
2021-06-08 01:23:25 +05:30
codeQualityHelpUrl: {
type: String,
required: false,
default: null,
},
2018-12-13 13:39:08 +05:30
},
computed: {
...mapState([
'isLoading',
'job',
'isSidebarOpen',
2021-11-18 22:05:49 +05:30
'jobLog',
'isJobLogComplete',
'jobLogSize',
'isJobLogSizeVisible',
2018-12-13 13:39:08 +05:30
'isScrollBottomDisabled',
'isScrollTopDisabled',
2021-11-18 22:05:49 +05:30
'isScrolledToBottomBeforeReceivingJobLog',
2018-12-13 13:39:08 +05:30
'hasError',
2019-09-04 21:01:54 +05:30
'selectedStage',
2018-12-13 13:39:08 +05:30
]),
...mapGetters([
'headerTime',
2019-07-07 11:18:12 +05:30
'hasUnmetPrerequisitesFailure',
2018-12-13 13:39:08 +05:30
'shouldRenderCalloutMessage',
'shouldRenderTriggeredLabel',
'hasEnvironment',
2019-07-07 11:18:12 +05:30
'shouldRenderSharedRunnerLimitWarning',
2021-11-18 22:05:49 +05:30
'hasJobLog',
2018-12-13 13:39:08 +05:30
'emptyStateIllustration',
'isScrollingDown',
'emptyStateAction',
'hasRunnersForProject',
]),
shouldRenderContent() {
return !this.isLoading && !this.hasError;
},
emptyStateTitle() {
const { emptyStateIllustration, remainingTime } = this;
const { title } = emptyStateIllustration;
if (this.isDelayedJob) {
return sprintf(title, { remainingTime });
}
return title;
},
2019-12-21 20:55:43 +05:30
shouldRenderHeaderCallout() {
return this.shouldRenderCalloutMessage && !this.hasUnmetPrerequisitesFailure;
},
2021-06-08 01:23:25 +05:30
shouldRenderCodeQualityWalkthrough() {
return this.job.status.group === 'failed-with-warnings';
},
2021-11-11 11:23:49 +05:30
itemName() {
return sprintf(__('Job %{jobName}'), { jobName: this.job.name });
},
2018-12-13 13:39:08 +05:30
},
watch: {
// Once the job log is loaded,
// fetch the stages for the dropdown on the sidebar
job(newVal, oldVal) {
2020-03-13 15:44:24 +05:30
if (isEmpty(oldVal) && !isEmpty(newVal.pipeline)) {
2019-09-04 21:01:54 +05:30
const stages = this.job.pipeline.details.stages || [];
2021-03-08 18:12:59 +05:30
const defaultStage = stages.find((stage) => stage && stage.name === this.selectedStage);
2019-09-04 21:01:54 +05:30
if (defaultStage) {
this.fetchJobsForStage(defaultStage);
}
2018-12-13 13:39:08 +05:30
}
},
},
created() {
2020-03-13 15:44:24 +05:30
this.throttled = throttle(this.toggleScrollButtons, 100);
2018-12-13 13:39:08 +05:30
window.addEventListener('resize', this.onResize);
window.addEventListener('scroll', this.updateScroll);
},
mounted() {
this.updateSidebar();
},
2020-03-13 15:44:24 +05:30
beforeDestroy() {
2021-11-18 22:05:49 +05:30
this.stopPollingJobLog();
2020-03-13 15:44:24 +05:30
this.stopPolling();
2018-12-13 13:39:08 +05:30
window.removeEventListener('resize', this.onResize);
window.removeEventListener('scroll', this.updateScroll);
},
methods: {
...mapActions([
2019-09-04 21:01:54 +05:30
'fetchJobsForStage',
2018-12-13 13:39:08 +05:30
'hideSidebar',
'showSidebar',
'toggleSidebar',
'scrollBottom',
'scrollTop',
2021-11-18 22:05:49 +05:30
'stopPollingJobLog',
2020-03-13 15:44:24 +05:30
'stopPolling',
2018-12-13 13:39:08 +05:30
'toggleScrollButtons',
'toggleScrollAnimation',
]),
onResize() {
this.updateSidebar();
this.updateScroll();
2018-12-05 23:21:45 +05:30
},
2018-12-13 13:39:08 +05:30
updateSidebar() {
2020-03-13 15:44:24 +05:30
const breakpoint = bp.getBreakpointSize();
if (breakpoint === 'xs' || breakpoint === 'sm') {
2018-12-13 13:39:08 +05:30
this.hideSidebar();
} else if (!this.isSidebarOpen) {
this.showSidebar();
}
2018-12-05 23:21:45 +05:30
},
2018-12-13 13:39:08 +05:30
updateScroll() {
if (!isScrolledToBottom()) {
this.toggleScrollAnimation(false);
} else if (this.isScrollingDown) {
this.toggleScrollAnimation(true);
}
this.throttled();
},
},
};
2018-12-05 23:21:45 +05:30
</script>
<template>
<div>
2021-06-08 01:23:25 +05:30
<gl-loading-icon v-if="isLoading" size="lg" class="qa-loading-animation gl-mt-6" />
2018-12-05 23:21:45 +05:30
2018-12-13 13:39:08 +05:30
<template v-else-if="shouldRenderContent">
2020-10-24 23:57:45 +05:30
<div class="build-page" data-testid="job-content">
2018-12-13 13:39:08 +05:30
<!-- Header Section -->
<header>
2020-10-24 23:57:45 +05:30
<div class="build-header top-area">
2018-12-13 13:39:08 +05:30
<ci-header
:status="job.status"
:time="headerTime"
:user="job.user"
:has-sidebar-button="true"
:should-render-triggered-label="shouldRenderTriggeredLabel"
2021-11-11 11:23:49 +05:30
:item-name="itemName"
2018-12-13 13:39:08 +05:30
@clickedSidebarButton="toggleSidebar"
/>
</div>
2021-02-22 17:27:13 +05:30
<gl-alert
v-if="shouldRenderHeaderCallout"
variant="danger"
class="gl-mt-3"
:dismissible="false"
>
2020-11-05 12:06:23 +05:30
<div v-safe-html="job.callout_message"></div>
2021-02-22 17:27:13 +05:30
</gl-alert>
2021-06-08 01:23:25 +05:30
<code-quality-walkthrough
v-if="shouldRenderCodeQualityWalkthrough"
step="troubleshoot_job"
:link="codeQualityHelpUrl"
/>
2018-12-13 13:39:08 +05:30
</header>
<!-- EO Header Section -->
<!-- Body Section -->
<stuck-block
v-if="job.stuck"
:has-no-runners-for-project="hasRunnersForProject"
:tags="job.tags"
:runners-path="runnerSettingsUrl"
/>
2019-07-07 11:18:12 +05:30
<unmet-prerequisites-block
v-if="hasUnmetPrerequisitesFailure"
:help-path="deploymentHelpUrl"
/>
<shared-runner
v-if="shouldRenderSharedRunnerLimitWarning"
:quota-used="job.runners.quota.used"
:quota-limit="job.runners.quota.limit"
2019-10-12 21:52:04 +05:30
:project-path="projectPath"
2019-12-04 20:38:33 +05:30
:subscriptions-more-minutes-url="subscriptionsMoreMinutesUrl"
2019-07-07 11:18:12 +05:30
/>
2018-12-13 13:39:08 +05:30
<environments-block
v-if="hasEnvironment"
:deployment-status="job.deployment_status"
2020-03-13 15:44:24 +05:30
:deployment-cluster="job.deployment_cluster"
2018-12-13 13:39:08 +05:30
:icon-status="job.status"
/>
<erased-block
v-if="job.erased_at"
2020-10-24 23:57:45 +05:30
data-testid="job-erased-block"
2018-12-13 13:39:08 +05:30
:user="job.erased_by"
:erased-at="job.erased_at"
/>
2019-02-15 15:39:39 +05:30
<div
2018-12-13 13:39:08 +05:30
v-if="job.archived"
2021-06-08 01:23:25 +05:30
class="gl-mt-3 gl-py-2 gl-px-3 gl-align-items-center gl-z-index-1 gl-m-auto archived-job"
2021-11-18 22:05:49 +05:30
:class="{ 'sticky-top gl-border-bottom-0': hasJobLog }"
2020-10-24 23:57:45 +05:30
data-testid="archived-job"
2018-12-13 13:39:08 +05:30
>
2021-06-08 01:23:25 +05:30
<gl-icon name="lock" class="gl-vertical-align-bottom" />
2018-12-13 13:39:08 +05:30
{{ __('This job is archived. Only the complete pipeline can be retried.') }}
</div>
2019-02-15 15:39:39 +05:30
<!-- job log -->
2019-03-02 22:35:43 +05:30
<div
2021-11-18 22:05:49 +05:30
v-if="hasJobLog"
class="build-log-container gl-relative"
2020-07-28 23:09:34 +05:30
:class="{ 'gl-mt-3': !job.archived }"
2019-03-02 22:35:43 +05:30
>
2018-12-13 13:39:08 +05:30
<log-top-bar
:class="{
'sidebar-expanded': isSidebarOpen,
'sidebar-collapsed': !isSidebarOpen,
2019-02-15 15:39:39 +05:30
'has-archived-block': job.archived,
2018-12-13 13:39:08 +05:30
}"
:erase-path="job.erase_path"
2021-11-18 22:05:49 +05:30
:size="jobLogSize"
2018-12-13 13:39:08 +05:30
:raw-path="job.raw_path"
:is-scroll-bottom-disabled="isScrollBottomDisabled"
:is-scroll-top-disabled="isScrollTopDisabled"
2021-11-18 22:05:49 +05:30
:is-job-log-size-visible="isJobLogSizeVisible"
2018-12-13 13:39:08 +05:30
:is-scrolling-down="isScrollingDown"
@scrollJobLogTop="scrollTop"
@scrollJobLogBottom="scrollBottom"
/>
2021-11-18 22:05:49 +05:30
<log :job-log="jobLog" :is-complete="isJobLogComplete" />
2018-12-05 23:21:45 +05:30
</div>
2018-12-13 13:39:08 +05:30
<!-- EO job log -->
2018-12-05 23:21:45 +05:30
2019-02-15 15:39:39 +05:30
<!-- empty state -->
2018-12-13 13:39:08 +05:30
<empty-state
2021-11-18 22:05:49 +05:30
v-if="!hasJobLog"
2018-12-13 13:39:08 +05:30
:illustration-path="emptyStateIllustration.image"
:illustration-size-class="emptyStateIllustration.size"
:title="emptyStateTitle"
:content="emptyStateIllustration.content"
:action="emptyStateAction"
2019-10-12 21:52:04 +05:30
:playable="job.playable"
:scheduled="job.scheduled"
2018-12-05 23:21:45 +05:30
/>
2019-02-15 15:39:39 +05:30
<!-- EO empty state -->
2018-12-05 23:21:45 +05:30
2019-02-15 15:39:39 +05:30
<!-- EO Body Section -->
2018-12-13 13:39:08 +05:30
</div>
2018-12-05 23:21:45 +05:30
</template>
2018-12-13 13:39:08 +05:30
<sidebar
v-if="shouldRenderContent"
:class="{
'right-sidebar-expanded': isSidebarOpen,
2019-02-15 15:39:39 +05:30
'right-sidebar-collapsed': !isSidebarOpen,
2018-12-13 13:39:08 +05:30
}"
2020-11-24 15:15:51 +05:30
:artifact-help-url="artifactHelpUrl"
2020-10-24 23:57:45 +05:30
data-testid="job-sidebar"
2018-12-13 13:39:08 +05:30
/>
2018-12-05 23:21:45 +05:30
</div>
</template>