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:
Diffstat (limited to 'app/assets/javascripts/pipelines/components/pipeline_details_header.vue')
-rw-r--r--app/assets/javascripts/pipelines/components/pipeline_details_header.vue200
1 files changed, 196 insertions, 4 deletions
diff --git a/app/assets/javascripts/pipelines/components/pipeline_details_header.vue b/app/assets/javascripts/pipelines/components/pipeline_details_header.vue
index e7cc55f95fa..7d4395dd579 100644
--- a/app/assets/javascripts/pipelines/components/pipeline_details_header.vue
+++ b/app/assets/javascripts/pipelines/components/pipeline_details_header.vue
@@ -1,9 +1,12 @@
<script>
-import { GlLoadingIcon } from '@gitlab/ui';
-import { __ } from '~/locale';
+import { GlBadge, GlIcon, GlLink, GlLoadingIcon, GlSprintf, GlTooltipDirective } from '@gitlab/ui';
+import { __, s__, sprintf } from '~/locale';
+import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import CiBadgeLink from '~/vue_shared/components/ci_badge_link.vue';
+import SafeHtml from '~/vue_shared/directives/safe_html';
import { LOAD_FAILURE, POST_FAILURE, DELETE_FAILURE, DEFAULT } from '../constants';
import getPipelineQuery from '../graphql/queries/get_pipeline_header_data.query.graphql';
+import TimeAgo from './pipelines_list/time_ago.vue';
import { getQueryHeaders } from './graph/utils';
const POLL_INTERVAL = 10000;
@@ -13,7 +16,41 @@ export default {
finishedStatuses: ['FAILED', 'SUCCESS', 'CANCELED'],
components: {
CiBadgeLink,
+ ClipboardButton,
+ GlBadge,
+ GlIcon,
+ GlLink,
GlLoadingIcon,
+ GlSprintf,
+ TimeAgo,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ SafeHtml,
+ },
+ i18n: {
+ scheduleBadgeText: s__('Pipelines|Scheduled'),
+ scheduleBadgeTooltip: __('This pipeline was triggered by a schedule'),
+ childBadgeText: s__('Pipelines|Child pipeline (%{linkStart}parent%{linkEnd})'),
+ childBadgeTooltip: __('This is a child pipeline within the parent pipeline'),
+ latestBadgeText: s__('Pipelines|latest'),
+ latestBadgeTooltip: __('Latest pipeline for the most recent commit on this branch'),
+ mergeTrainBadgeText: s__('Pipelines|merge train'),
+ mergeTrainBadgeTooltip: s__(
+ 'Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch.',
+ ),
+ invalidBadgeText: s__('Pipelines|yaml invalid'),
+ failedBadgeText: s__('Pipelines|error'),
+ autoDevopsBadgeText: s__('Pipelines|Auto DevOps'),
+ autoDevopsBadgeTooltip: __(
+ 'This pipeline makes use of a predefined CI/CD configuration enabled by Auto DevOps.',
+ ),
+ detachedBadgeText: s__('Pipelines|merge request'),
+ detachedBadgeTooltip: s__(
+ "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch.",
+ ),
+ stuckBadgeText: s__('Pipelines|stuck'),
+ stuckBadgeTooltip: s__('Pipelines|This pipeline is stuck'),
},
errorTexts: {
[LOAD_FAILURE]: __('We are currently unable to fetch data for the pipeline header.'),
@@ -58,6 +95,11 @@ export default {
required: false,
default: '',
},
+ refText: {
+ type: String,
+ required: false,
+ default: '',
+ },
badges: {
type: Object,
required: false,
@@ -76,7 +118,9 @@ export default {
iid: this.pipelineIid,
};
},
- update: (data) => data.project.pipeline,
+ update(data) {
+ return data.project.pipeline;
+ },
error() {
this.reportFailure(LOAD_FAILURE);
},
@@ -150,6 +194,36 @@ export default {
};
}
},
+ usersName() {
+ return this.pipeline?.user?.name || '';
+ },
+ userPath() {
+ return this.pipeline?.user?.webPath || '';
+ },
+ shortId() {
+ return this.pipeline?.commit?.shortId || '';
+ },
+ commitPath() {
+ return this.pipeline?.commit?.webPath || '';
+ },
+ totalJobsText() {
+ return sprintf(__('%{jobs} Jobs'), {
+ jobs: this.totalJobs,
+ });
+ },
+ triggeredText() {
+ return sprintf(__('%{linkStart}%{name}%{linkEnd} triggered pipeline for commit'), {
+ name: this.usersName,
+ });
+ },
+ inProgress() {
+ return this.status === 'RUNNING';
+ },
+ inProgressText() {
+ return sprintf(__('In progress, queued for %{queuedDuration} seconds'), {
+ queuedDuration: this.pipeline?.queuedDuration || 0,
+ });
+ },
},
methods: {
reportFailure(errorType, errorMessages = []) {
@@ -164,8 +238,126 @@ export default {
<div class="gl-mt-3">
<gl-loading-icon v-if="loading" class="gl-text-left" size="lg" />
<template v-else>
- <div class="gl-mb-2">
+ <h3 v-if="name" class="gl-mt-0 gl-mb-2" data-testid="pipeline-name">{{ name }}</h3>
+ <div>
<ci-badge-link :status="detailedStatus" />
+ <div class="gl-ml-2 gl-mb-2 gl-display-inline-block gl-h-6">
+ <gl-sprintf :message="triggeredText">
+ <template #link="{ content }">
+ <gl-link
+ :href="userPath"
+ class="gl-text-gray-900 gl-font-weight-bold"
+ target="_blank"
+ >
+ {{ content }}
+ </gl-link>
+ </template>
+ </gl-sprintf>
+ <gl-link
+ :href="commitPath"
+ class="gl-bg-blue-50 gl-rounded-base gl-px-2 gl-mx-2"
+ data-testid="commit-link"
+ >
+ {{ shortId }}
+ </gl-link>
+ <clipboard-button
+ :text="shortId"
+ category="tertiary"
+ :title="__('Copy commit SHA')"
+ size="small"
+ />
+ <time-ago
+ v-if="isFinished"
+ :pipeline="pipeline"
+ class="gl-display-inline gl-mb-0"
+ :display-calendar-icon="false"
+ font-size="gl-font-md"
+ />
+ </div>
+ </div>
+ <div v-safe-html="refText" class="gl-mb-2" data-testid="pipeline-ref-text"></div>
+ <div>
+ <gl-badge
+ v-if="badges.schedule"
+ v-gl-tooltip
+ :title="$options.i18n.scheduleBadgeTooltip"
+ variant="info"
+ >
+ {{ $options.i18n.scheduleBadgeText }}
+ </gl-badge>
+ <gl-badge
+ v-if="badges.child"
+ v-gl-tooltip
+ :title="$options.i18n.childBadgeTooltip"
+ variant="info"
+ >
+ <gl-sprintf :message="$options.i18n.childBadgeText">
+ <template #link="{ content }">
+ <gl-link :href="paths.triggeredByPath" target="_blank">
+ {{ content }}
+ </gl-link>
+ </template>
+ </gl-sprintf>
+ </gl-badge>
+ <gl-badge
+ v-if="badges.latest"
+ v-gl-tooltip
+ :title="$options.i18n.latestBadgeTooltip"
+ variant="success"
+ >
+ {{ $options.i18n.latestBadgeText }}
+ </gl-badge>
+ <gl-badge
+ v-if="badges.mergeTrainPipeline"
+ v-gl-tooltip
+ :title="$options.i18n.mergeTrainBadgeTooltip"
+ variant="info"
+ >
+ {{ $options.i18n.mergeTrainBadgeText }}
+ </gl-badge>
+ <gl-badge v-if="badges.invalid" v-gl-tooltip :title="yamlErrors" variant="danger">
+ {{ $options.i18n.invalidBadgeText }}
+ </gl-badge>
+ <gl-badge v-if="badges.failed" v-gl-tooltip :title="failureReason" variant="danger">
+ {{ $options.i18n.failedBadgeText }}
+ </gl-badge>
+ <gl-badge
+ v-if="badges.autoDevops"
+ v-gl-tooltip
+ :title="$options.i18n.autoDevopsBadgeTooltip"
+ variant="info"
+ >
+ {{ $options.i18n.autoDevopsBadgeText }}
+ </gl-badge>
+ <gl-badge
+ v-if="badges.detached"
+ v-gl-tooltip
+ :title="$options.i18n.detachedBadgeTooltip"
+ variant="info"
+ data-qa-selector="merge_request_badge_tag"
+ >
+ {{ $options.i18n.detachedBadgeText }}
+ </gl-badge>
+ <gl-badge
+ v-if="badges.stuck"
+ v-gl-tooltip
+ :title="$options.i18n.stuckBadgeTooltip"
+ variant="warning"
+ >
+ {{ $options.i18n.stuckBadgeText }}
+ </gl-badge>
+ <span class="gl-ml-2" data-testid="total-jobs">
+ <gl-icon name="pipeline" />
+ {{ totalJobsText }}
+ </span>
+ <span v-if="isFinished" class="gl-ml-2" data-testid="compute-credits">
+ <gl-icon name="quota" />
+ {{ computeCredits }}
+ </span>
+ <span v-if="inProgress" class="gl-ml-2" data-testid="pipeline-running-text">
+ <gl-icon name="timer" />
+ {{ inProgressText }}
+ </span>
</div>
</template>
</div>