1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
<script>
import { GlTooltipDirective } from '@gitlab/ui';
import { sprintf, s__ } from '~/locale';
import CiBadgeLink from '~/vue_shared/components/ci_badge_link.vue';
import { accessValue } from './accessors/linked_pipelines_accessors';
/**
* Renders the upstream/downstream portions of the pipeline mini graph.
*/
export default {
directives: {
GlTooltip: GlTooltipDirective,
},
components: {
CiBadgeLink,
},
inject: {
dataMethod: {
default: 'rest',
},
},
props: {
triggeredBy: {
type: Array,
required: false,
default: () => [],
},
triggered: {
type: Array,
required: false,
default: () => [],
},
pipelinePath: {
type: String,
required: false,
default: '',
},
},
data() {
return {
maxRenderedPipelines: 3,
};
},
computed: {
// Exactly one of these (triggeredBy and triggered) must be truthy. Never both. Never neither.
isUpstream() {
return Boolean(this.triggeredBy.length) && !this.triggered.length;
},
isDownstream() {
return !this.triggeredBy.length && Boolean(this.triggered.length);
},
linkedPipelines() {
return this.isUpstream ? this.triggeredBy : this.triggered;
},
totalPipelineCount() {
return this.linkedPipelines.length;
},
linkedPipelinesTrimmed() {
return this.totalPipelineCount > this.maxRenderedPipelines
? this.linkedPipelines.slice(0, this.maxRenderedPipelines)
: this.linkedPipelines;
},
shouldRenderCounter() {
return this.isDownstream && this.linkedPipelines.length > this.maxRenderedPipelines;
},
counterLabel() {
return `+${this.linkedPipelines.length - this.maxRenderedPipelines}`;
},
counterTooltipText() {
return sprintf(s__('LinkedPipelines|%{counterLabel} more downstream pipelines'), {
counterLabel: this.counterLabel,
});
},
},
methods: {
pipelineTooltipText(pipeline) {
const { label } = accessValue(pipeline, this.dataMethod, 'detailedStatus');
return `${pipeline.project.name} - ${label}`;
},
pipelineStatus(pipeline) {
// detailedStatus is graphQL, details.status is REST
return pipeline?.detailedStatus || pipeline?.details?.status;
},
triggerButtonClass(pipeline) {
const { group } = accessValue(pipeline, this.dataMethod, 'detailedStatus');
return `ci-status-icon-${group}`;
},
},
};
</script>
<template>
<span
v-if="linkedPipelines"
:class="{
'is-upstream': isUpstream,
'is-downstream': isDownstream,
}"
class="linked-pipeline-mini-list gl-display-inline gl-vertical-align-middle"
>
<ci-badge-link
v-for="pipeline in linkedPipelinesTrimmed"
:key="pipeline.id"
v-gl-tooltip="{ title: pipelineTooltipText(pipeline) }"
:status="pipelineStatus(pipeline)"
size="md"
:show-text="false"
:show-tooltip="false"
:class="triggerButtonClass(pipeline)"
class="linked-pipeline-mini-item gl-mb-0!"
data-testid="linked-pipeline-mini-item"
/>
<a
v-if="shouldRenderCounter"
v-gl-tooltip="{ title: counterTooltipText }"
:title="counterTooltipText"
:href="pipelinePath"
class="gl-align-items-center gl-bg-gray-50 gl-display-inline-flex gl-font-sm gl-h-6 gl-justify-content-center gl-rounded-pill gl-text-decoration-none gl-text-gray-500 gl-w-7 linked-pipelines-counter linked-pipeline-mini-item"
data-testid="linked-pipeline-counter"
>
{{ counterLabel }}
</a>
</span>
</template>
|