diff options
Diffstat (limited to 'app/assets/javascripts/pipelines/components/graph')
3 files changed, 82 insertions, 15 deletions
diff --git a/app/assets/javascripts/pipelines/components/graph/graph_component.vue b/app/assets/javascripts/pipelines/components/graph/graph_component.vue index 429122c8083..4dc6e51d2fc 100644 --- a/app/assets/javascripts/pipelines/components/graph/graph_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/graph_component.vue @@ -43,7 +43,7 @@ export default { downstream: 'downstream', data() { return { - triggeredTopIndex: 1, + downstreamMarginTop: null, }; }, computed: { @@ -77,26 +77,34 @@ export default { expandedTriggered() { return this.pipeline.triggered && this.pipeline.triggered.find(el => el.isExpanded); }, - - /** - * Calculates the margin top of the clicked downstream pipeline by - * adding the height of each linked pipeline and the margin - */ - marginTop() { - return `${this.triggeredTopIndex * 52}px`; - }, pipelineTypeUpstream() { return this.type !== this.$options.downstream && this.expandedTriggeredBy; }, pipelineTypeDownstream() { return this.type !== this.$options.upstream && this.expandedTriggered; }, + pipelineProjectId() { + return this.pipeline.project.id; + }, }, methods: { - handleClickedDownstream(pipeline, clickedIndex) { - this.triggeredTopIndex = clickedIndex; + handleClickedDownstream(pipeline, clickedIndex, downstreamNode) { + /** + * Calculates the margin top of the clicked downstream pipeline by + * subtracting the clicked downstream pipelines offsetTop by it's parent's + * offsetTop and then subtracting either 15 (if child) or 30 (if not a child) + * due to the height of node and stage name margin bottom. + */ + this.downstreamMarginTop = this.calculateMarginTop( + downstreamNode, + downstreamNode.classList.contains('child-pipeline') ? 15 : 30, + ); + this.$emit('onClickTriggered', this.pipeline, pipeline); }, + calculateMarginTop(downstreamNode, pixelDiff) { + return `${downstreamNode.offsetTop - downstreamNode.offsetParent.offsetTop - pixelDiff}px`; + }, hasOnlyOneJob(stage) { return stage.groups.length === 1; }, @@ -139,6 +147,7 @@ export default { v-if="hasTriggeredBy" :linked-pipelines="triggeredByPipelines" :column-title="__('Upstream')" + :project-id="pipelineProjectId" graph-position="left" @linkedPipelineClick=" linkedPipeline => $emit('onClickTriggeredBy', pipeline, linkedPipeline) @@ -174,6 +183,7 @@ export default { v-if="hasTriggered" :linked-pipelines="triggeredPipelines" :column-title="__('Downstream')" + :project-id="pipelineProjectId" graph-position="right" @linkedPipelineClick="handleClickedDownstream" /> @@ -186,7 +196,7 @@ export default { :is-loading="false" :pipeline="expandedTriggered" :is-linked-pipeline="true" - :style="{ 'margin-top': marginTop }" + :style="{ 'margin-top': downstreamMarginTop }" :mediator="mediator" @onClickTriggered=" (parentPipeline, pipeline) => clickTriggeredPipeline(parentPipeline, pipeline) diff --git a/app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue b/app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue index 82335e71403..d929398b6dc 100644 --- a/app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue +++ b/app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue @@ -1,6 +1,7 @@ <script> import { GlLoadingIcon, GlTooltipDirective, GlButton } from '@gitlab/ui'; import CiStatus from '~/vue_shared/components/ci_icon.vue'; +import { __ } from '~/locale'; export default { directives: { @@ -16,6 +17,14 @@ export default { type: Object, required: true, }, + projectId: { + type: Number, + required: true, + }, + columnTitle: { + type: String, + required: true, + }, }, computed: { tooltipText() { @@ -30,18 +39,45 @@ export default { projectName() { return this.pipeline.project.name; }, + parentPipeline() { + // Refactor string match when BE returns Upstream/Downstream indicators + return this.projectId === this.pipeline.project.id && this.columnTitle === __('Upstream'); + }, + childPipeline() { + // Refactor string match when BE returns Upstream/Downstream indicators + return this.projectId === this.pipeline.project.id && this.columnTitle === __('Downstream'); + }, + label() { + return this.parentPipeline ? __('Parent') : __('Child'); + }, + childTooltipText() { + return __('This pipeline was triggered by a parent pipeline'); + }, + parentTooltipText() { + return __('This pipeline triggered a child pipeline'); + }, + labelToolTipText() { + return this.label === __('Parent') ? this.parentTooltipText : this.childTooltipText; + }, }, methods: { onClickLinkedPipeline() { this.$root.$emit('bv::hide::tooltip', this.buttonId); - this.$emit('pipelineClicked'); + this.$emit('pipelineClicked', this.$refs.linkedPipeline); + }, + hideTooltips() { + this.$root.$emit('bv::hide::tooltip'); }, }, }; </script> <template> - <li class="linked-pipeline build"> + <li + ref="linkedPipeline" + class="linked-pipeline build" + :class="{ 'child-pipeline': childPipeline }" + > <gl-button :id="buttonId" v-gl-tooltip @@ -59,6 +95,15 @@ export default { class="js-linked-pipeline-status" /> <span class="str-truncated align-bottom"> {{ projectName }} • #{{ pipeline.id }} </span> + <div v-if="parentPipeline || childPipeline" class="parent-child-label-container"> + <span + v-gl-tooltip.bottom + :title="labelToolTipText" + class="badge badge-primary" + @mouseover="hideTooltips" + >{{ label }}</span + > + </div> </gl-button> </li> </template> diff --git a/app/assets/javascripts/pipelines/components/graph/linked_pipelines_column.vue b/app/assets/javascripts/pipelines/components/graph/linked_pipelines_column.vue index 998519f9df1..e3429184c05 100644 --- a/app/assets/javascripts/pipelines/components/graph/linked_pipelines_column.vue +++ b/app/assets/javascripts/pipelines/components/graph/linked_pipelines_column.vue @@ -19,6 +19,10 @@ export default { type: String, required: true, }, + projectId: { + type: Number, + required: true, + }, }, computed: { columnClass() { @@ -28,10 +32,16 @@ export default { }; return `graph-position-${this.graphPosition} ${positionValues[this.graphPosition]}`; }, + // Refactor string match when BE returns Upstream/Downstream indicators isUpstream() { return this.columnTitle === __('Upstream'); }, }, + methods: { + onPipelineClick(downstreamNode, pipeline, index) { + this.$emit('linkedPipelineClick', pipeline, index, downstreamNode); + }, + }, }; </script> @@ -48,7 +58,9 @@ export default { 'left-connector': pipeline.isExpanded && graphPosition === 'left', }" :pipeline="pipeline" - @pipelineClicked="$emit('linkedPipelineClick', pipeline, index)" + :column-title="columnTitle" + :project-id="projectId" + @pipelineClicked="onPipelineClick($event, pipeline, index)" /> </ul> </div> |