Commit 92d18d7a authored by Payton Burdette's avatar Payton Burdette 2️⃣ Committed by Filipa Lacerda
Browse files

Port over more pipeline files to ce

This commit ports over some files I missed
in my first commit because I forgot to stage
them in the first commit.
parent 37a7dd8e
Loading
Loading
Loading
Loading
+164 −5
Original line number Diff line number Diff line
<script>
import _ from 'underscore';
import { GlLoadingIcon } from '@gitlab/ui';
import StageColumnComponent from './stage_column_component.vue';
import GraphMixin from '../../mixins/graph_component_mixin';
import GraphWidthMixin from '~/pipelines/mixins/graph_width_mixin';
import GraphWidthMixin from '../../mixins/graph_width_mixin';
import LinkedPipelinesColumn from './linked_pipelines_column.vue';
import GraphBundleMixin from '../../mixins/graph_pipeline_bundle_mixin';

export default {
  name: 'PipelineGraph',
  components: {
    StageColumnComponent,
    GlLoadingIcon,
    LinkedPipelinesColumn,
  },
  mixins: [GraphMixin, GraphWidthMixin, GraphBundleMixin],
  props: {
    isLoading: {
      type: Boolean,
      required: true,
    },
    pipeline: {
      type: Object,
      required: true,
    },
    isLinkedPipeline: {
      type: Boolean,
      required: false,
      default: false,
    },
    mediator: {
      type: Object,
      required: true,
    },
    type: {
      type: String,
      required: false,
      default: 'main',
    },
  },
  upstream: 'upstream',
  downstream: 'downstream',
  data() {
    return {
      triggeredTopIndex: 1,
    };
  },
  computed: {
    hasTriggeredBy() {
      return (
        this.type !== this.$options.downstream &&
        this.triggeredByPipelines &&
        this.pipeline.triggered_by !== null
      );
    },
    triggeredByPipelines() {
      return this.pipeline.triggered_by;
    },
    hasTriggered() {
      return (
        this.type !== this.$options.upstream &&
        this.triggeredPipelines &&
        this.pipeline.triggered.length > 0
      );
    },
    triggeredPipelines() {
      return this.pipeline.triggered;
    },
    expandedTriggeredBy() {
      return (
        this.pipeline.triggered_by &&
        _.isArray(this.pipeline.triggered_by) &&
        this.pipeline.triggered_by.find(el => el.isExpanded)
      );
    },
    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;
    },
  },
  methods: {
    handleClickedDownstream(pipeline, clickedIndex) {
      this.triggeredTopIndex = clickedIndex;
      this.$emit('onClickTriggered', this.pipeline, pipeline);
    },
    hasOnlyOneJob(stage) {
      return stage.groups.length === 1;
    },
    hasDownstream(index, length) {
      return index === length - 1 && this.hasTriggered;
    },
    hasUpstream(index) {
      return index === 0 && this.hasTriggeredBy;
    },
  },
  mixins: [GraphMixin, GraphWidthMixin],
};
</script>
<template>
  <div class="build-content middle-block js-pipeline-graph">
    <div class="pipeline-visualization pipeline-graph pipeline-tab-content">
    <div
      class="pipeline-visualization pipeline-graph"
      :class="{ 'pipeline-tab-content': !isLinkedPipeline }"
    >
      <div
        :style="{
          paddingLeft: `${graphLeftPadding}px`,
@@ -23,21 +123,80 @@ export default {
      >
        <gl-loading-icon v-if="isLoading" class="m-auto" :size="3" />

        <ul v-if="!isLoading" class="stage-column-list">
        <pipeline-graph
          v-if="pipelineTypeUpstream"
          type="upstream"
          class="d-inline-block upstream-pipeline"
          :class="`js-upstream-pipeline-${expandedTriggeredBy.id}`"
          :is-loading="false"
          :pipeline="expandedTriggeredBy"
          :is-linked-pipeline="true"
          :mediator="mediator"
          @onClickTriggeredBy="
            (parentPipeline, pipeline) => clickTriggeredByPipeline(parentPipeline, pipeline)
          "
          @refreshPipelineGraph="requestRefreshPipelineGraph"
        />

        <linked-pipelines-column
          v-if="hasTriggeredBy"
          :linked-pipelines="triggeredByPipelines"
          :column-title="__('Upstream')"
          graph-position="left"
          @linkedPipelineClick="
            linkedPipeline => $emit('onClickTriggeredBy', pipeline, linkedPipeline)
          "
        />

        <ul
          v-if="!isLoading"
          :class="{
            'inline js-has-linked-pipelines': hasTriggered || hasTriggeredBy,
          }"
          class="stage-column-list align-top"
        >
          <stage-column-component
            v-for="(stage, index) in graph"
            :key="stage.name"
            :class="{
              'append-right-48': shouldAddRightMargin(index),
              'has-upstream prepend-left-64': hasUpstream(index),
              'has-downstream': hasDownstream(index, graph.length),
              'has-only-one-job': hasOnlyOneJob(stage),
              'append-right-46': shouldAddRightMargin(index),
            }"
            :title="capitalizeStageName(stage.name)"
            :groups="stage.groups"
            :stage-connector-class="stageConnectorClass(index, stage)"
            :is-first-column="isFirstColumn(index)"
            :has-triggered-by="hasTriggeredBy"
            :action="stage.status.action"
            @refreshPipelineGraph="refreshPipelineGraph"
          />
        </ul>

        <linked-pipelines-column
          v-if="hasTriggered"
          :linked-pipelines="triggeredPipelines"
          :column-title="__('Downstream')"
          graph-position="right"
          @linkedPipelineClick="handleClickedDownstream"
        />

        <pipeline-graph
          v-if="pipelineTypeDownstream"
          type="downstream"
          class="d-inline-block"
          :class="`js-downstream-pipeline-${expandedTriggered.id}`"
          :is-loading="false"
          :pipeline="expandedTriggered"
          :is-linked-pipeline="true"
          :style="{ 'margin-top': marginTop }"
          :mediator="mediator"
          @onClickTriggered="
            (parentPipeline, pipeline) => clickTriggeredPipeline(parentPipeline, pipeline)
          "
          @refreshPipelineGraph="requestRefreshPipelineGraph"
        />
      </div>
    </div>
  </div>
+1 −1
Original line number Diff line number Diff line
<script>
import _ from 'underscore';
import stageColumnMixin from 'ee_else_ce/pipelines/mixins/stage_column_mixin';
import stageColumnMixin from '../../mixins/stage_column_mixin';
import JobItem from './job_item.vue';
import JobGroupDropdown from './job_group_dropdown.vue';
import ActionComponent from './action_component.vue';
+56 −4
Original line number Diff line number Diff line
import Flash from '~/flash';
import flash from '~/flash';
import { __ } from '~/locale';

export default {
  methods: {
    clickTriggeredByPipeline() {},
    clickTriggeredPipeline() {},
    getExpandedPipelines(pipeline) {
      this.mediator.service
        .getPipeline(this.mediator.getExpandedParameters())
        .then(response => {
          this.mediator.store.toggleLoading(pipeline);
          this.mediator.store.storePipeline(response.data);
          this.mediator.poll.enable({ data: this.mediator.getExpandedParameters() });
        })
        .catch(() => {
          this.mediator.store.toggleLoading(pipeline);
          flash(__('An error occurred while fetching the pipeline.'));
        });
    },
    /**
     * Called when a linked pipeline is clicked.
     *
     * If the pipeline is collapsed we will start polling it & we will reset the other pipelines.
     * If the pipeline is expanded we will close it.
     *
     * @param {String} method Method to fetch the pipeline
     * @param {String} storeKey Store property that will be updates
     * @param {String} resetStoreKey Store key for the visible pipeline that will need to be reset
     * @param {Object} pipeline The clicked pipeline
     */
    clickPipeline(parentPipeline, pipeline, openMethod, closeMethod) {
      if (!pipeline.isExpanded) {
        this.mediator.store[openMethod](parentPipeline, pipeline);
        this.mediator.store.toggleLoading(pipeline);
        this.mediator.poll.stop();

        this.getExpandedPipelines(pipeline);
      } else {
        this.mediator.store[closeMethod](pipeline);
        this.mediator.poll.stop();

        this.mediator.poll.enable({ data: this.mediator.getExpandedParameters() });
      }
    },
    clickTriggeredByPipeline(parentPipeline, pipeline) {
      this.clickPipeline(
        parentPipeline,
        pipeline,
        'openTriggeredByPipeline',
        'closeTriggeredByPipeline',
      );
    },
    clickTriggeredPipeline(parentPipeline, pipeline) {
      this.clickPipeline(
        parentPipeline,
        pipeline,
        'openTriggeredPipeline',
        'closeTriggeredPipeline',
      );
    },
    requestRefreshPipelineGraph() {
      // When an action is clicked
      // (wether in the dropdown or in the main nodes, we refresh the big graph)
      this.mediator
        .refreshPipeline()
        .catch(() => Flash(__('An error occurred while making the request.')));
        .catch(() => flash(__('An error occurred while making the request.')));
    },
  },
};
Loading