summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/pipelines
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/pipelines')
-rw-r--r--app/assets/javascripts/pipelines/components/dag/dag.vue4
-rw-r--r--app/assets/javascripts/pipelines/components/dag/dag_graph.vue4
-rw-r--r--app/assets/javascripts/pipelines/components/graph/action_component.vue3
-rw-r--r--app/assets/javascripts/pipelines/components/graph/constants.js6
-rw-r--r--app/assets/javascripts/pipelines/components/graph/graph_component.vue21
-rw-r--r--app/assets/javascripts/pipelines/components/graph/graph_component_legacy.vue2
-rw-r--r--app/assets/javascripts/pipelines/components/graph/job_item.vue7
-rw-r--r--app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue3
-rw-r--r--app/assets/javascripts/pipelines/components/graph/linked_pipelines_column.vue29
-rw-r--r--app/assets/javascripts/pipelines/components/graph/stage_column_component.vue18
-rw-r--r--app/assets/javascripts/pipelines/components/graph_shared/drawing_utils.js4
-rw-r--r--app/assets/javascripts/pipelines/components/graph_shared/links_inner.vue22
-rw-r--r--app/assets/javascripts/pipelines/components/graph_shared/links_layer.vue6
-rw-r--r--app/assets/javascripts/pipelines/components/legacy_header_component.vue132
-rw-r--r--app/assets/javascripts/pipelines/components/pipeline_graph/pipeline_graph.vue26
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue9
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue8
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipelines_actions.vue68
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table.vue2
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table_row.vue8
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/stage.vue135
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_branch_name_token.vue2
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_tag_name_token.vue2
-rw-r--r--app/assets/javascripts/pipelines/components/test_reports/test_case_details.vue38
-rw-r--r--app/assets/javascripts/pipelines/components/test_reports/test_suite_table.vue2
-rw-r--r--app/assets/javascripts/pipelines/pipeline_details_bundle.js97
-rw-r--r--app/assets/javascripts/pipelines/pipeline_details_dag.js2
-rw-r--r--app/assets/javascripts/pipelines/pipeline_details_mediator.js2
-rw-r--r--app/assets/javascripts/pipelines/services/pipelines_service.js2
-rw-r--r--app/assets/javascripts/pipelines/stores/test_reports/actions.js10
-rw-r--r--app/assets/javascripts/pipelines/stores/test_reports/utils.js10
-rw-r--r--app/assets/javascripts/pipelines/utils.js4
32 files changed, 292 insertions, 396 deletions
diff --git a/app/assets/javascripts/pipelines/components/dag/dag.vue b/app/assets/javascripts/pipelines/components/dag/dag.vue
index 2482af2c7f0..23e7ce349cf 100644
--- a/app/assets/javascripts/pipelines/components/dag/dag.vue
+++ b/app/assets/javascripts/pipelines/components/dag/dag.vue
@@ -4,11 +4,11 @@ import { isEmpty } from 'lodash';
import { __ } from '~/locale';
import { fetchPolicies } from '~/lib/graphql';
import getDagVisData from '../../graphql/queries/get_dag_vis_data.query.graphql';
+import { parseData } from '../parsing_utils';
+import { DEFAULT, PARSE_FAILURE, LOAD_FAILURE, UNSUPPORTED_DATA } from '../../constants';
import DagGraph from './dag_graph.vue';
import DagAnnotations from './dag_annotations.vue';
import { ADD_NOTE, REMOVE_NOTE, REPLACE_NOTES } from './constants';
-import { parseData } from '../parsing_utils';
-import { DEFAULT, PARSE_FAILURE, LOAD_FAILURE, UNSUPPORTED_DATA } from '../../constants';
export default {
// eslint-disable-next-line @gitlab/require-i18n-strings
diff --git a/app/assets/javascripts/pipelines/components/dag/dag_graph.vue b/app/assets/javascripts/pipelines/components/dag/dag_graph.vue
index 5ba0604fa01..76ccbd74bb6 100644
--- a/app/assets/javascripts/pipelines/components/dag/dag_graph.vue
+++ b/app/assets/javascripts/pipelines/components/dag/dag_graph.vue
@@ -1,6 +1,8 @@
<script>
import * as d3 from 'd3';
import { uniqueId } from 'lodash';
+import { getMaxNodes, removeOrphanNodes } from '../parsing_utils';
+import { PARSE_FAILURE } from '../../constants';
import { LINK_SELECTOR, NODE_SELECTOR, ADD_NOTE, REMOVE_NOTE, REPLACE_NOTES } from './constants';
import {
currentIsLive,
@@ -10,9 +12,7 @@ import {
toggleLinkHighlight,
togglePathHighlights,
} from './interactions';
-import { getMaxNodes, removeOrphanNodes } from '../parsing_utils';
import { calculateClip, createLinkPath, createSankey, labelPosition } from './drawing_utils';
-import { PARSE_FAILURE } from '../../constants';
export default {
viewOptions: {
diff --git a/app/assets/javascripts/pipelines/components/graph/action_component.vue b/app/assets/javascripts/pipelines/components/graph/action_component.vue
index 0ce94d4f02f..949d0d30297 100644
--- a/app/assets/javascripts/pipelines/components/graph/action_component.vue
+++ b/app/assets/javascripts/pipelines/components/graph/action_component.vue
@@ -3,6 +3,7 @@ import { GlTooltipDirective, GlButton, GlLoadingIcon, GlIcon } from '@gitlab/ui'
import axios from '~/lib/utils/axios_utils';
import { dasherize } from '~/lib/utils/text_utility';
import { __ } from '~/locale';
+import { BV_HIDE_TOOLTIP } from '~/lib/utils/constants';
import { deprecatedCreateFlash as createFlash } from '~/flash';
import { reportToSentry } from './utils';
@@ -62,7 +63,7 @@ export default {
*
*/
onClickAction() {
- this.$root.$emit('bv::hide::tooltip', `js-ci-action-${this.link}`);
+ this.$root.$emit(BV_HIDE_TOOLTIP, `js-ci-action-${this.link}`);
this.isDisabled = true;
this.isLoading = true;
diff --git a/app/assets/javascripts/pipelines/components/graph/constants.js b/app/assets/javascripts/pipelines/components/graph/constants.js
index 6f0deccfef6..caa269f5095 100644
--- a/app/assets/javascripts/pipelines/components/graph/constants.js
+++ b/app/assets/javascripts/pipelines/components/graph/constants.js
@@ -2,5 +2,11 @@ export const DOWNSTREAM = 'downstream';
export const MAIN = 'main';
export const UPSTREAM = 'upstream';
+/*
+ this value is based on the gl-pipeline-job-width class
+ plus some extra for the margins
+*/
+export const ONE_COL_WIDTH = 180;
+
export const REST = 'rest';
export const GRAPHQL = 'graphql';
diff --git a/app/assets/javascripts/pipelines/components/graph/graph_component.vue b/app/assets/javascripts/pipelines/components/graph/graph_component.vue
index cd403757fe6..cae26e6ee3f 100644
--- a/app/assets/javascripts/pipelines/components/graph/graph_component.vue
+++ b/app/assets/javascripts/pipelines/components/graph/graph_component.vue
@@ -3,7 +3,7 @@ import LinkedGraphWrapper from '../graph_shared/linked_graph_wrapper.vue';
import LinksLayer from '../graph_shared/links_layer.vue';
import LinkedPipelinesColumn from './linked_pipelines_column.vue';
import StageColumnComponent from './stage_column_component.vue';
-import { DOWNSTREAM, MAIN, UPSTREAM } from './constants';
+import { DOWNSTREAM, MAIN, UPSTREAM, ONE_COL_WIDTH } from './constants';
import { reportToSentry } from './utils';
export default {
@@ -86,11 +86,11 @@ export default {
reportToSentry(this.$options.name, `error: ${err}, info: ${info}`);
},
mounted() {
- this.measurements = this.getMeasurements();
+ this.getMeasurements();
},
methods: {
getMeasurements() {
- return {
+ this.measurements = {
width: this.$refs[this.containerId].scrollWidth,
height: this.$refs[this.containerId].scrollHeight,
};
@@ -101,6 +101,13 @@ export default {
setJob(jobName) {
this.hoveredJobName = jobName;
},
+ slidePipelineContainer() {
+ this.$refs.mainPipelineContainer.scrollBy({
+ left: ONE_COL_WIDTH,
+ top: 0,
+ behavior: 'smooth',
+ });
+ },
togglePipelineExpanded(jobName, expanded) {
this.pipelineExpanded = {
expanded,
@@ -116,8 +123,9 @@ export default {
<template>
<div class="js-pipeline-graph">
<div
- class="gl-display-flex gl-position-relative gl-overflow-auto gl-bg-gray-10 gl-white-space-nowrap"
- :class="{ 'gl-pipeline-min-h gl-py-5': !isLinkedPipeline }"
+ ref="mainPipelineContainer"
+ class="gl-display-flex gl-position-relative gl-bg-gray-10 gl-white-space-nowrap"
+ :class="{ 'gl-pipeline-min-h gl-py-5 gl-overflow-auto': !isLinkedPipeline }"
>
<linked-graph-wrapper>
<template #upstream>
@@ -153,6 +161,7 @@ export default {
:pipeline-id="pipeline.id"
@refreshPipelineGraph="$emit('refreshPipelineGraph')"
@jobHover="setJob"
+ @updateMeasurements="getMeasurements"
/>
</links-layer>
</div>
@@ -160,11 +169,13 @@ export default {
<template #downstream>
<linked-pipelines-column
v-if="showDownstreamPipelines"
+ class="gl-mr-6"
:linked-pipelines="downstreamPipelines"
:column-title="__('Downstream')"
:type="$options.pipelineTypeConstants.DOWNSTREAM"
@downstreamHovered="setJob"
@pipelineExpandToggle="togglePipelineExpanded"
+ @scrollContainer="slidePipelineContainer"
@error="onError"
/>
</template>
diff --git a/app/assets/javascripts/pipelines/components/graph/graph_component_legacy.vue b/app/assets/javascripts/pipelines/components/graph/graph_component_legacy.vue
index 2164dbf4d55..818985a74d1 100644
--- a/app/assets/javascripts/pipelines/components/graph/graph_component_legacy.vue
+++ b/app/assets/javascripts/pipelines/components/graph/graph_component_legacy.vue
@@ -1,9 +1,9 @@
<script>
import { escape, capitalize } from 'lodash';
import { GlLoadingIcon } from '@gitlab/ui';
+import GraphBundleMixin from '../../mixins/graph_pipeline_bundle_mixin';
import StageColumnComponentLegacy from './stage_column_component_legacy.vue';
import LinkedPipelinesColumnLegacy from './linked_pipelines_column_legacy.vue';
-import GraphBundleMixin from '../../mixins/graph_pipeline_bundle_mixin';
import { UPSTREAM, DOWNSTREAM, MAIN } from './constants';
import { reportToSentry } from './utils';
diff --git a/app/assets/javascripts/pipelines/components/graph/job_item.vue b/app/assets/javascripts/pipelines/components/graph/job_item.vue
index 8262d728a24..52848fe3ade 100644
--- a/app/assets/javascripts/pipelines/components/graph/job_item.vue
+++ b/app/assets/javascripts/pipelines/components/graph/job_item.vue
@@ -1,9 +1,10 @@
<script>
import { GlTooltipDirective, GlLink } from '@gitlab/ui';
-import ActionComponent from './action_component.vue';
-import JobNameComponent from './job_name_component.vue';
import { sprintf } from '~/locale';
import delayedJobMixin from '~/jobs/mixins/delayed_job_mixin';
+import { BV_HIDE_TOOLTIP } from '~/lib/utils/constants';
+import ActionComponent from './action_component.vue';
+import JobNameComponent from './job_name_component.vue';
import { accessValue } from './accessors';
import { REST } from './constants';
import { reportToSentry } from './utils';
@@ -144,7 +145,7 @@ export default {
},
methods: {
hideTooltips() {
- this.$root.$emit('bv::hide::tooltip');
+ this.$root.$emit(BV_HIDE_TOOLTIP);
},
pipelineActionRequestComplete() {
this.$emit('pipelineActionRequestComplete');
diff --git a/app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue b/app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue
index d18e604f087..22f9fb72159 100644
--- a/app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue
+++ b/app/assets/javascripts/pipelines/components/graph/linked_pipeline.vue
@@ -2,6 +2,7 @@
import { GlTooltipDirective, GlButton, GlLink, GlLoadingIcon, GlBadge } from '@gitlab/ui';
import CiStatus from '~/vue_shared/components/ci_icon.vue';
import { __, sprintf } from '~/locale';
+import { BV_HIDE_TOOLTIP } from '~/lib/utils/constants';
import { accessValue } from './accessors';
import { DOWNSTREAM, REST, UPSTREAM } from './constants';
import { reportToSentry } from './utils';
@@ -126,7 +127,7 @@ export default {
this.$emit('pipelineExpandToggle', this.sourceJobName, !this.expanded);
},
hideTooltips() {
- this.$root.$emit('bv::hide::tooltip');
+ this.$root.$emit(BV_HIDE_TOOLTIP);
},
onDownstreamHovered() {
this.$emit('downstreamHovered', this.sourceJobName);
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 40e6a01b88c..079e938ddd4 100644
--- a/app/assets/javascripts/pipelines/components/graph/linked_pipelines_column.vue
+++ b/app/assets/javascripts/pipelines/components/graph/linked_pipelines_column.vue
@@ -1,8 +1,8 @@
<script>
import getPipelineDetails from 'shared_queries/pipelines/get_pipeline_details.query.graphql';
-import LinkedPipeline from './linked_pipeline.vue';
import { LOAD_FAILURE } from '../../constants';
-import { UPSTREAM } from './constants';
+import LinkedPipeline from './linked_pipeline.vue';
+import { ONE_COL_WIDTH, UPSTREAM } from './constants';
import { unwrapPipelineData, toggleQueryPollingByVisibility, reportToSentry } from './utils';
export default {
@@ -39,6 +39,7 @@ export default {
'gl-pl-3',
'gl-mb-5',
],
+ minWidth: `${ONE_COL_WIDTH}px`,
computed: {
columnClass() {
const positionValues = {
@@ -47,12 +48,6 @@ export default {
};
return `graph-position-${this.graphPosition} ${positionValues[this.graphPosition]}`;
},
- graphPosition() {
- return this.isUpstream ? 'left' : 'right';
- },
- isUpstream() {
- return this.type === UPSTREAM;
- },
computedTitleClasses() {
const positionalClasses = this.isUpstream
? ['gl-w-full', 'gl-text-right', 'gl-linked-pipeline-padding']
@@ -60,6 +55,12 @@ export default {
return [...this.$options.titleClasses, ...positionalClasses];
},
+ graphPosition() {
+ return this.isUpstream ? 'left' : 'right';
+ },
+ isUpstream() {
+ return this.type === UPSTREAM;
+ },
},
methods: {
getPipelineData(pipeline) {
@@ -79,6 +80,7 @@ export default {
},
result() {
this.loadingPipelineId = null;
+ this.$emit('scrollContainer');
},
error(err, _vm, _key, type) {
this.$emit('error', LOAD_FAILURE);
@@ -130,6 +132,9 @@ export default {
this.$emit('pipelineExpandToggle', jobName, expanded);
},
+ showDownstreamContainer(id) {
+ return !this.isUpstream && (this.isExpanded(id) || this.isLoadingPipeline(id));
+ },
},
};
</script>
@@ -158,9 +163,13 @@ export default {
@pipelineClicked="onPipelineClick(pipeline)"
@pipelineExpandToggle="onPipelineExpandToggle"
/>
- <div v-if="isExpanded(pipeline.id)" class="gl-display-inline-block">
+ <div
+ v-if="showDownstreamContainer(pipeline.id)"
+ :style="{ minWidth: $options.minWidth }"
+ class="gl-display-inline-block"
+ >
<pipeline-graph
- v-if="currentPipeline"
+ v-if="isExpanded(pipeline.id)"
:type="type"
class="d-inline-block gl-mt-n2"
:pipeline="currentPipeline"
diff --git a/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue b/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue
index 65f8c231885..b258c885abb 100644
--- a/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue
+++ b/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue
@@ -67,6 +67,9 @@ export default {
errorCaptured(err, _vm, info) {
reportToSentry('stage_column_component', `error: ${err}, info: ${info}`);
},
+ mounted() {
+ this.$emit('updateMeasurements');
+ },
methods: {
getGroupId(group) {
return accessValue(GRAPHQL, 'groupId', group);
@@ -75,11 +78,7 @@ export default {
return `ci-badge-${escape(group.name)}`;
},
isFadedOut(jobName) {
- return (
- this.jobHovered &&
- this.highlightedJobs.length > 1 &&
- !this.highlightedJobs.includes(jobName)
- );
+ return this.highlightedJobs.length > 1 && !this.highlightedJobs.includes(jobName);
},
},
};
@@ -123,12 +122,9 @@ export default {
:class="{ 'gl-opacity-3': isFadedOut(group.name) }"
@pipelineActionRequestComplete="$emit('refreshPipelineGraph')"
/>
- <job-group-dropdown
- v-else
- :group="group"
- :pipeline-id="pipelineId"
- :class="{ 'gl-opacity-3': isFadedOut(group.name) }"
- />
+ <div v-else :class="{ 'gl-opacity-3': isFadedOut(group.name) }">
+ <job-group-dropdown :group="group" :pipeline-id="pipelineId" />
+ </div>
</div>
</template>
</main-graph-wrapper>
diff --git a/app/assets/javascripts/pipelines/components/graph_shared/drawing_utils.js b/app/assets/javascripts/pipelines/components/graph_shared/drawing_utils.js
index 65c215be794..202498fb188 100644
--- a/app/assets/javascripts/pipelines/components/graph_shared/drawing_utils.js
+++ b/app/assets/javascripts/pipelines/components/graph_shared/drawing_utils.js
@@ -40,10 +40,10 @@ export const generateLinksData = ({ links }, containerID, modifier = '') => {
// positioned in the center of the job node by adding half the height
// of the job pill.
const paddingLeft = parseFloat(
- window.getComputedStyle(containerEl, null).getPropertyValue('padding-left'),
+ window.getComputedStyle(containerEl, null).getPropertyValue('padding-left') || 0,
);
const paddingTop = parseFloat(
- window.getComputedStyle(containerEl, null).getPropertyValue('padding-top'),
+ window.getComputedStyle(containerEl, null).getPropertyValue('padding-top') || 0,
);
const sourceNodeX = sourceNodeCoordinates.right - containerCoordinates.x - paddingLeft;
diff --git a/app/assets/javascripts/pipelines/components/graph_shared/links_inner.vue b/app/assets/javascripts/pipelines/components/graph_shared/links_inner.vue
index 89444076ae0..289e04e02c5 100644
--- a/app/assets/javascripts/pipelines/components/graph_shared/links_inner.vue
+++ b/app/assets/javascripts/pipelines/components/graph_shared/links_inner.vue
@@ -118,22 +118,20 @@ export default {
<div class="gl-display-flex gl-relative">
<svg
id="link-svg"
- class="gl-absolute"
+ class="gl-absolute gl-pointer-events-none"
:viewBox="viewBox"
:width="`${containerMeasurements.width}px`"
:height="`${containerMeasurements.height}px`"
>
- <template>
- <path
- v-for="link in links"
- :key="link.path"
- :ref="link.ref"
- :d="link.path"
- class="gl-fill-transparent gl-transition-duration-slow gl-transition-timing-function-ease"
- :class="getLinkClasses(link)"
- :stroke-width="$options.STROKE_WIDTH"
- />
- </template>
+ <path
+ v-for="link in links"
+ :key="link.path"
+ :ref="link.ref"
+ :d="link.path"
+ class="gl-fill-transparent gl-transition-duration-slow gl-transition-timing-function-ease"
+ :class="getLinkClasses(link)"
+ :stroke-width="$options.STROKE_WIDTH"
+ />
</svg>
<slot></slot>
</div>
diff --git a/app/assets/javascripts/pipelines/components/graph_shared/links_layer.vue b/app/assets/javascripts/pipelines/components/graph_shared/links_layer.vue
index 0993892a574..1c1bc7ecb2a 100644
--- a/app/assets/javascripts/pipelines/components/graph_shared/links_layer.vue
+++ b/app/assets/javascripts/pipelines/components/graph_shared/links_layer.vue
@@ -74,13 +74,15 @@ export default {
<div v-else>
<gl-alert
v-if="showAlert"
- class="gl-w-max-content gl-ml-4"
+ class="gl-ml-4 gl-mb-4"
:primary-button-text="$options.i18n.showLinksAnyways"
@primaryAction="overrideShowLinks"
@dismiss="dismissAlert"
>
{{ $options.i18n.tooManyJobs }}
</gl-alert>
- <slot></slot>
+ <div class="gl-display-flex gl-relative">
+ <slot></slot>
+ </div>
</div>
</template>
diff --git a/app/assets/javascripts/pipelines/components/legacy_header_component.vue b/app/assets/javascripts/pipelines/components/legacy_header_component.vue
deleted file mode 100644
index c7b72be36ad..00000000000
--- a/app/assets/javascripts/pipelines/components/legacy_header_component.vue
+++ /dev/null
@@ -1,132 +0,0 @@
-<script>
-import { GlLoadingIcon, GlModal, GlModalDirective, GlButton } from '@gitlab/ui';
-import ciHeader from '~/vue_shared/components/header_ci_component.vue';
-import eventHub from '../event_hub';
-import { __ } from '~/locale';
-
-const DELETE_MODAL_ID = 'pipeline-delete-modal';
-
-export default {
- name: 'PipelineHeaderSection',
- components: {
- ciHeader,
- GlLoadingIcon,
- GlModal,
- GlButton,
- },
- directives: {
- GlModal: GlModalDirective,
- },
- props: {
- pipeline: {
- type: Object,
- required: true,
- },
- isLoading: {
- type: Boolean,
- required: true,
- },
- },
- data() {
- return {
- isCanceling: false,
- isRetrying: false,
- isDeleting: false,
- };
- },
-
- computed: {
- status() {
- return this.pipeline.details && this.pipeline.details.status;
- },
- shouldRenderContent() {
- return !this.isLoading && Object.keys(this.pipeline).length;
- },
- deleteModalConfirmationText() {
- return __(
- 'Are you sure you want to delete this pipeline? Doing so will expire all pipeline caches and delete all related objects, such as builds, logs, artifacts, and triggers. This action cannot be undone.',
- );
- },
- },
-
- methods: {
- cancelPipeline() {
- this.isCanceling = true;
- eventHub.$emit('headerPostAction', this.pipeline.cancel_path);
- },
- retryPipeline() {
- this.isRetrying = true;
- eventHub.$emit('headerPostAction', this.pipeline.retry_path);
- },
- deletePipeline() {
- this.isDeleting = true;
- eventHub.$emit('headerDeleteAction', this.pipeline.delete_path);
- },
- },
- DELETE_MODAL_ID,
-};
-</script>
-<template>
- <div class="pipeline-header-container">
- <ci-header
- v-if="shouldRenderContent"
- :status="status"
- :item-id="pipeline.id"
- :time="pipeline.created_at"
- :user="pipeline.user"
- item-name="Pipeline"
- >
- <gl-button
- v-if="pipeline.retry_path"
- :loading="isRetrying"
- :disabled="isRetrying"
- data-testid="retryButton"
- category="secondary"
- variant="info"
- @click="retryPipeline()"
- >
- {{ __('Retry') }}
- </gl-button>
-
- <gl-button
- v-if="pipeline.cancel_path"
- :loading="isCanceling"
- :disabled="isCanceling"
- data-testid="cancelPipeline"
- class="gl-ml-3"
- category="primary"
- variant="danger"
- @click="cancelPipeline()"
- >
- {{ __('Cancel running') }}
- </gl-button>
-
- <gl-button
- v-if="pipeline.delete_path"
- v-gl-modal="$options.DELETE_MODAL_ID"
- :loading="isDeleting"
- :disabled="isDeleting"
- data-testid="deletePipeline"
- class="gl-ml-3"
- category="secondary"
- variant="danger"
- >
- {{ __('Delete') }}
- </gl-button>
- </ci-header>
-
- <gl-loading-icon v-if="isLoading" size="lg" class="gl-mt-3 gl-mb-3" />
-
- <gl-modal
- :modal-id="$options.DELETE_MODAL_ID"
- :title="__('Delete pipeline')"
- :ok-title="__('Delete pipeline')"
- ok-variant="danger"
- @ok="deletePipeline()"
- >
- <p>
- {{ deleteModalConfirmationText }}
- </p>
- </gl-modal>
- </div>
-</template>
diff --git a/app/assets/javascripts/pipelines/components/pipeline_graph/pipeline_graph.vue b/app/assets/javascripts/pipelines/components/pipeline_graph/pipeline_graph.vue
index 8636808b69e..678678b87eb 100644
--- a/app/assets/javascripts/pipelines/components/pipeline_graph/pipeline_graph.vue
+++ b/app/assets/javascripts/pipelines/components/pipeline_graph/pipeline_graph.vue
@@ -1,13 +1,13 @@
<script>
import { GlAlert } from '@gitlab/ui';
import { __ } from '~/locale';
+import { CI_CONFIG_STATUS_INVALID } from '~/pipeline_editor/constants';
import { generateLinksData } from '../graph_shared/drawing_utils';
-import JobPill from './job_pill.vue';
-import StagePill from './stage_pill.vue';
import { parseData } from '../parsing_utils';
import { DRAW_FAILURE, DEFAULT, INVALID_CI_CONFIG, EMPTY_PIPELINE_DATA } from '../../constants';
import { createJobsHash, generateJobNeedsDict } from '../../utils';
-import { CI_CONFIG_STATUS_INVALID } from '~/pipeline_editor/constants';
+import StagePill from './stage_pill.vue';
+import JobPill from './job_pill.vue';
export default {
components: {
@@ -224,17 +224,15 @@ export default {
data-testid="graph-container"
>
<svg :viewBox="viewBox" :width="width" :height="height" class="gl-absolute">
- <template>
- <path
- v-for="link in links"
- :key="link.path"
- :ref="link.ref"
- :d="link.path"
- class="gl-fill-transparent gl-transition-duration-slow gl-transition-timing-function-ease"
- :class="getLinkClasses(link)"
- :stroke-width="$options.STROKE_WIDTH"
- />
- </template>
+ <path
+ v-for="link in links"
+ :key="link.path"
+ :ref="link.ref"
+ :d="link.path"
+ class="gl-fill-transparent gl-transition-duration-slow gl-transition-timing-function-ease"
+ :class="getLinkClasses(link)"
+ :stroke-width="$options.STROKE_WIDTH"
+ />
</svg>
<div
v-for="(stage, index) in pipelineStages"
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue
index d1bac078642..823ada133d2 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue
@@ -77,6 +77,15 @@ export default {
>{{ __('latest') }}</gl-badge
>
<gl-badge
+ v-if="pipeline.flags.merge_train_pipeline"
+ v-gl-tooltip
+ :title="__('This is a merge train pipeline')"
+ variant="info"
+ size="sm"
+ data-testid="pipeline-url-train"
+ >{{ __('train') }}</gl-badge
+ >
+ <gl-badge
v-if="pipeline.flags.yaml_errors"
v-gl-tooltip
:title="pipeline.yaml_errors"
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue
index ec7c5764be1..b4eb429748f 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue
@@ -3,16 +3,16 @@ import { isEqual } from 'lodash';
import { GlIcon } from '@gitlab/ui';
import { __, s__ } from '~/locale';
import { deprecatedCreateFlash as createFlash } from '~/flash';
-import PipelinesService from '../../services/pipelines_service';
-import pipelinesMixin from '../../mixins/pipelines';
import TablePagination from '~/vue_shared/components/pagination/table_pagination.vue';
import NavigationTabs from '~/vue_shared/components/navigation_tabs.vue';
-import NavigationControls from './nav_controls.vue';
import { getParameterByName } from '~/lib/utils/common_utils';
import CIPaginationMixin from '~/vue_shared/mixins/ci_pagination_api_mixin';
-import PipelinesFilteredSearch from './pipelines_filtered_search.vue';
+import pipelinesMixin from '../../mixins/pipelines';
+import PipelinesService from '../../services/pipelines_service';
import { validateParams } from '../../utils';
import { ANY_TRIGGER_AUTHOR, RAW_TEXT_WARNING, FILTER_TAG_IDENTIFIER } from '../../constants';
+import NavigationControls from './nav_controls.vue';
+import PipelinesFilteredSearch from './pipelines_filtered_search.vue';
export default {
components: {
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_actions.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_actions.vue
index 1ea71610897..13f314a3a45 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_actions.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_actions.vue
@@ -1,7 +1,7 @@
<script>
-import { GlTooltipDirective, GlButton, GlLoadingIcon, GlIcon } from '@gitlab/ui';
+import { GlDropdown, GlDropdownItem, GlIcon, GlTooltipDirective } from '@gitlab/ui';
import axios from '~/lib/utils/axios_utils';
-import { deprecatedCreateFlash as flash } from '~/flash';
+import createFlash from '~/flash';
import { s__, __, sprintf } from '~/locale';
import GlCountdown from '~/vue_shared/components/gl_countdown.vue';
import eventHub from '../../event_hub';
@@ -11,10 +11,10 @@ export default {
GlTooltip: GlTooltipDirective,
},
components: {
- GlIcon,
GlCountdown,
- GlButton,
- GlLoadingIcon,
+ GlDropdown,
+ GlDropdownItem,
+ GlIcon,
},
props: {
actions: {
@@ -61,7 +61,7 @@ export default {
})
.catch(() => {
this.isLoading = false;
- flash(__('An error occurred while making the request.'));
+ createFlash({ message: __('An error occurred while making the request.') });
});
},
@@ -76,39 +76,27 @@ export default {
};
</script>
<template>
- <div class="btn-group">
- <button
- v-gl-tooltip
- type="button"
- :disabled="isLoading"
- class="dropdown-new btn btn-default js-pipeline-dropdown-manual-actions"
- :title="__('Run manual or delayed jobs')"
- data-toggle="dropdown"
- :aria-label="__('Run manual or delayed jobs')"
+ <gl-dropdown
+ v-gl-tooltip
+ :title="__('Run manual or delayed jobs')"
+ :loading="isLoading"
+ data-testid="pipelines-manual-actions-dropdown"
+ right
+ icon="play"
+ >
+ <gl-dropdown-item
+ v-for="action in actions"
+ :key="action.path"
+ :disabled="isActionDisabled(action)"
+ @click="onClickAction(action)"
>
- <gl-icon name="play" class="icon-play" />
- <gl-icon name="chevron-down" />
- <gl-loading-icon v-if="isLoading" />
- </button>
-
- <ul class="dropdown-menu dropdown-menu-right">
- <li v-for="action in actions" :key="action.path">
- <gl-button
- category="tertiary"
- :class="{ disabled: isActionDisabled(action) }"
- :disabled="isActionDisabled(action)"
- class="js-pipeline-action-link"
- @click="onClickAction(action)"
- >
- <div class="d-flex justify-content-between flex-wrap">
- {{ action.name }}
- <span v-if="action.scheduled_at">
- <gl-icon name="clock" />
- <gl-countdown :end-date-string="action.scheduled_at" />
- </span>
- </div>
- </gl-button>
- </li>
- </ul>
- </div>
+ <div class="gl-display-flex gl-justify-content-space-between gl-flex-wrap">
+ {{ action.name }}
+ <span v-if="action.scheduled_at">
+ <gl-icon name="clock" />
+ <gl-countdown :end-date-string="action.scheduled_at" />
+ </span>
+ </div>
+ </gl-dropdown-item>
+ </gl-dropdown>
</template>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table.vue
index 6c60594efca..1b08f883b05 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table.vue
@@ -1,8 +1,8 @@
<script>
import { GlTooltipDirective } from '@gitlab/ui';
+import eventHub from '../../event_hub';
import PipelinesTableRowComponent from './pipelines_table_row.vue';
import PipelineStopModal from './pipeline_stop_modal.vue';
-import eventHub from '../../event_hub';
/**
* Pipelines Table Component.
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table_row.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table_row.vue
index b6c4e617a90..5231fe0b112 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table_row.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table_row.vue
@@ -1,16 +1,16 @@
<script>
import { GlButton, GlTooltipDirective, GlModalDirective } from '@gitlab/ui';
-import eventHub from '../../event_hub';
import { __ } from '~/locale';
+import CiBadge from '~/vue_shared/components/ci_badge_link.vue';
+import CommitComponent from '~/vue_shared/components/commit.vue';
+import eventHub from '../../event_hub';
+import { PIPELINES_TABLE } from '../../constants';
import PipelinesActionsComponent from './pipelines_actions.vue';
import PipelinesArtifactsComponent from './pipelines_artifacts.vue';
-import CiBadge from '~/vue_shared/components/ci_badge_link.vue';
import PipelineStage from './stage.vue';
import PipelineUrl from './pipeline_url.vue';
import PipelineTriggerer from './pipeline_triggerer.vue';
import PipelinesTimeago from './time_ago.vue';
-import CommitComponent from '~/vue_shared/components/commit.vue';
-import { PIPELINES_TABLE } from '../../constants';
/**
* Pipeline table row.
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/stage.vue b/app/assets/javascripts/pipelines/components/pipelines_list/stage.vue
index a9154d93194..460aa427196 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/stage.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/stage.vue
@@ -11,11 +11,11 @@
* 3. Merge request widget
* 4. Commit widget
*/
-
import $ from 'jquery';
-import { GlLoadingIcon, GlTooltipDirective, GlIcon } from '@gitlab/ui';
+import { GlDropdown, GlLoadingIcon, GlTooltipDirective, GlIcon } from '@gitlab/ui';
import { __ } from '~/locale';
import { deprecatedCreateFlash as Flash } from '~/flash';
+import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import axios from '~/lib/utils/axios_utils';
import eventHub from '../../event_hub';
import JobItem from '../graph/job_item.vue';
@@ -24,14 +24,14 @@ import { PIPELINES_TABLE } from '../../constants';
export default {
components: {
GlIcon,
- JobItem,
GlLoadingIcon,
+ GlDropdown,
+ JobItem,
},
-
directives: {
GlTooltip: GlTooltipDirective,
},
-
+ mixins: [glFeatureFlagsMixin()],
props: {
stage: {
type: Object,
@@ -50,30 +50,25 @@ export default {
default: '',
},
},
-
data() {
return {
isLoading: false,
- dropdownContent: '',
+ dropdownContent: [],
};
},
-
computed: {
- dropdownClass() {
- return this.dropdownContent.length > 0
- ? 'js-builds-dropdown-container'
- : 'js-builds-dropdown-loading';
+ isCiMiniPipelineGlDropdown() {
+ // Feature flag ci_mini_pipeline_gl_dropdown
+ // See more at https://gitlab.com/gitlab-org/gitlab/-/issues/300400
+ return this.glFeatures?.ciMiniPipelineGlDropdown;
},
-
triggerButtonClass() {
return `ci-status-icon-${this.stage.status.group}`;
},
-
borderlessIcon() {
return `${this.stage.status.icon}_borderless`;
},
},
-
watch: {
updateDropdown() {
if (this.updateDropdown && this.isDropdownOpen() && !this.isLoading) {
@@ -81,14 +76,17 @@ export default {
}
},
},
-
updated() {
- if (this.dropdownContent.length > 0) {
+ if (!this.isCiMiniPipelineGlDropdown && this.dropdownContent.length) {
this.stopDropdownClickPropagation();
}
},
-
methods: {
+ onShowDropdown() {
+ eventHub.$emit('clickedDropdown');
+ this.isLoading = true;
+ this.fetchJobs();
+ },
onClickStage() {
if (!this.isDropdownOpen()) {
eventHub.$emit('clickedDropdown');
@@ -96,7 +94,6 @@ export default {
this.fetchJobs();
}
},
-
fetchJobs() {
axios
.get(this.stage.dropdown_path)
@@ -105,13 +102,16 @@ export default {
this.isLoading = false;
})
.catch(() => {
- this.closeDropdown();
+ if (this.isCiMiniPipelineGlDropdown) {
+ this.$refs.stageGlDropdown.hide();
+ } else {
+ this.closeDropdown();
+ }
this.isLoading = false;
Flash(__('Something went wrong on our end.'));
});
},
-
/**
* When the user right clicks or cmd/ctrl + click in the job name
* the dropdown should not be closed and the link should open in another tab,
@@ -119,6 +119,8 @@ export default {
*
* Since this component is rendered multiple times per page we need to guarantee we only
* target the click event of this component.
+ *
+ * Note: This should be removed once ci_mini_pipeline_gl_dropdown FF is removed as true.
*/
stopDropdownClickPropagation() {
$(
@@ -128,23 +130,24 @@ export default {
e.stopPropagation();
});
},
-
closeDropdown() {
if (this.isDropdownOpen()) {
$(this.$refs.dropdown).dropdown('toggle');
}
},
-
isDropdownOpen() {
return this.$el.classList.contains('show');
},
-
pipelineActionRequestComplete() {
if (this.type === PIPELINES_TABLE) {
// warn the table to update
eventHub.$emit('refreshPipelinesTable');
+ return;
+ }
+ // close the dropdown in mr widget
+ if (this.isCiMiniPipelineGlDropdown) {
+ this.$refs.stageGlDropdown.hide();
} else {
- // close the dropdown in mr widget
$(this.$refs.dropdown).dropdown('toggle');
}
},
@@ -154,31 +157,30 @@ export default {
<template>
<div class="dropdown">
- <button
- id="stageDropdown"
- ref="dropdown"
+ <gl-dropdown
+ v-if="isCiMiniPipelineGlDropdown"
+ ref="stageGlDropdown"
v-gl-tooltip.hover
- :class="triggerButtonClass"
+ data-testid="mini-pipeline-graph-dropdown"
:title="stage.title"
- class="mini-pipeline-graph-dropdown-toggle js-builds-dropdown-button"
- data-toggle="dropdown"
- data-display="static"
- type="button"
- aria-haspopup="true"
- aria-expanded="false"
- @click="onClickStage"
- >
- <span :aria-label="stage.title" aria-hidden="true" class="gl-pointer-events-none">
- <gl-icon :name="borderlessIcon" />
- </span>
- </button>
-
- <div
- class="dropdown-menu mini-pipeline-graph-dropdown-menu js-builds-dropdown-container"
- aria-labelledby="stageDropdown"
+ variant="link"
+ :lazy="true"
+ :popper-opts="{ placement: 'bottom' }"
+ :toggle-class="['mini-pipeline-graph-gl-dropdown-toggle', triggerButtonClass]"
+ menu-class="mini-pipeline-graph-dropdown-menu"
+ @show="onShowDropdown"
>
+ <template #button-content>
+ <span class="gl-pointer-events-none">
+ <gl-icon :name="borderlessIcon" />
+ </span>
+ </template>
<gl-loading-icon v-if="isLoading" />
- <ul v-else class="js-builds-dropdown-list scrollable-menu">
+ <ul
+ v-else
+ class="js-builds-dropdown-list scrollable-menu"
+ data-testid="mini-pipeline-graph-dropdown-menu-list"
+ >
<li v-for="job in dropdownContent" :key="job.id">
<job-item
:dropdown-length="dropdownContent.length"
@@ -188,6 +190,45 @@ export default {
/>
</li>
</ul>
- </div>
+ </gl-dropdown>
+
+ <template v-else>
+ <button
+ id="stageDropdown"
+ ref="dropdown"
+ v-gl-tooltip.hover
+ :class="triggerButtonClass"
+ :title="stage.title"
+ class="mini-pipeline-graph-dropdown-toggle"
+ data-testid="mini-pipeline-graph-dropdown-toggle"
+ data-toggle="dropdown"
+ data-display="static"
+ type="button"
+ aria-haspopup="true"
+ aria-expanded="false"
+ @click="onClickStage"
+ >
+ <span :aria-label="stage.title" aria-hidden="true" class="gl-pointer-events-none">
+ <gl-icon :name="borderlessIcon" />
+ </span>
+ </button>
+
+ <div
+ class="dropdown-menu mini-pipeline-graph-dropdown-menu js-builds-dropdown-container"
+ aria-labelledby="stageDropdown"
+ >
+ <gl-loading-icon v-if="isLoading" />
+ <ul v-else class="js-builds-dropdown-list scrollable-menu">
+ <li v-for="job in dropdownContent" :key="job.id">
+ <job-item
+ :dropdown-length="dropdownContent.length"
+ :job="job"
+ css-class-job-name="mini-pipeline-graph-dropdown-item"
+ @pipelineActionRequestComplete="pipelineActionRequestComplete"
+ />
+ </li>
+ </ul>
+ </div>
+ </template>
</div>
</template>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_branch_name_token.vue b/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_branch_name_token.vue
index 24456574a6f..20a232beb83 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_branch_name_token.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_branch_name_token.vue
@@ -2,8 +2,8 @@
import { GlFilteredSearchToken, GlFilteredSearchSuggestion, GlLoadingIcon } from '@gitlab/ui';
import { debounce } from 'lodash';
import Api from '~/api';
-import { FETCH_BRANCH_ERROR_MESSAGE, FILTER_PIPELINES_SEARCH_DELAY } from '../../../constants';
import { deprecatedCreateFlash as createFlash } from '~/flash';
+import { FETCH_BRANCH_ERROR_MESSAGE, FILTER_PIPELINES_SEARCH_DELAY } from '../../../constants';
export default {
components: {
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_tag_name_token.vue b/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_tag_name_token.vue
index 1241803c612..4a8d89ebe37 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_tag_name_token.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_tag_name_token.vue
@@ -2,8 +2,8 @@
import { GlFilteredSearchToken, GlFilteredSearchSuggestion, GlLoadingIcon } from '@gitlab/ui';
import { debounce } from 'lodash';
import Api from '~/api';
-import { FETCH_TAG_ERROR_MESSAGE, FILTER_PIPELINES_SEARCH_DELAY } from '../../../constants';
import { deprecatedCreateFlash as createFlash } from '~/flash';
+import { FETCH_TAG_ERROR_MESSAGE, FILTER_PIPELINES_SEARCH_DELAY } from '../../../constants';
export default {
components: {
diff --git a/app/assets/javascripts/pipelines/components/test_reports/test_case_details.vue b/app/assets/javascripts/pipelines/components/test_reports/test_case_details.vue
index 504cf138d07..08f296bec12 100644
--- a/app/assets/javascripts/pipelines/components/test_reports/test_case_details.vue
+++ b/app/assets/javascripts/pipelines/components/test_reports/test_case_details.vue
@@ -1,12 +1,13 @@
<script>
-import { GlModal } from '@gitlab/ui';
-import { __ } from '~/locale';
+import { GlBadge, GlModal } from '@gitlab/ui';
+import { __, n__, sprintf } from '~/locale';
import CodeBlock from '~/vue_shared/components/code_block.vue';
export default {
name: 'TestCaseDetails',
components: {
CodeBlock,
+ GlBadge,
GlModal,
},
props: {
@@ -21,9 +22,35 @@ export default {
Boolean(classname) && Boolean(formattedTime) && Boolean(name),
},
},
+ computed: {
+ failureHistoryMessage() {
+ if (!this.hasRecentFailures) {
+ return null;
+ }
+
+ return sprintf(
+ n__(
+ 'Reports|Failed %{count} time in %{baseBranch} in the last 14 days',
+ 'Reports|Failed %{count} times in %{baseBranch} in the last 14 days',
+ this.recentFailures.count,
+ ),
+ {
+ count: this.recentFailures.count,
+ baseBranch: this.recentFailures.base_branch,
+ },
+ );
+ },
+ hasRecentFailures() {
+ return Boolean(this.recentFailures);
+ },
+ recentFailures() {
+ return this.testCase.recent_failures;
+ },
+ },
text: {
name: __('Name'),
duration: __('Execution time'),
+ history: __('History'),
trace: __('System output'),
},
modalCloseButton: {
@@ -53,6 +80,13 @@ export default {
</div>
</div>
+ <div v-if="testCase.recent_failures" class="gl-display-flex gl-flex-wrap gl-mx-n4 gl-my-3">
+ <strong class="gl-text-right col-sm-3">{{ $options.text.history }}</strong>
+ <div class="col-sm-9" data-testid="test-case-recent-failures">
+ <gl-badge variant="warning">{{ failureHistoryMessage }}</gl-badge>
+ </div>
+ </div>
+
<div
v-if="testCase.system_output"
class="gl-display-flex gl-flex-wrap gl-mx-n4 gl-my-3"
diff --git a/app/assets/javascripts/pipelines/components/test_reports/test_suite_table.vue b/app/assets/javascripts/pipelines/components/test_reports/test_suite_table.vue
index 4b4fb6082c6..6b7381883cc 100644
--- a/app/assets/javascripts/pipelines/components/test_reports/test_suite_table.vue
+++ b/app/assets/javascripts/pipelines/components/test_reports/test_suite_table.vue
@@ -114,7 +114,7 @@ export default {
<div role="rowheader" class="table-mobile-header">{{ __('Status') }}</div>
<div class="table-mobile-content text-center">
<div
- class="add-border ci-status-icon d-flex align-items-center justify-content-end justify-content-md-center"
+ class="ci-status-icon d-flex align-items-center justify-content-end justify-content-md-center"
:class="`ci-status-icon-${testCase.status}`"
>
<gl-icon :size="24" :name="testCase.icon" />
diff --git a/app/assets/javascripts/pipelines/pipeline_details_bundle.js b/app/assets/javascripts/pipelines/pipeline_details_bundle.js
index 133608b9801..5ee5b45aac9 100644
--- a/app/assets/javascripts/pipelines/pipeline_details_bundle.js
+++ b/app/assets/javascripts/pipelines/pipeline_details_bundle.js
@@ -2,12 +2,9 @@ import Vue from 'vue';
import { deprecatedCreateFlash as Flash } from '~/flash';
import Translate from '~/vue_shared/translate';
import { __ } from '~/locale';
-import { setUrlFragment, redirectTo } from '~/lib/utils/url_utility';
import PipelineGraphLegacy from './components/graph/graph_component_legacy.vue';
import createDagApp from './pipeline_details_dag';
import GraphBundleMixin from './mixins/graph_pipeline_bundle_mixin';
-import legacyPipelineHeader from './components/legacy_header_component.vue';
-import eventHub from './event_hub';
import TestReports from './components/test_reports/test_reports.vue';
import createTestReportsStore from './stores/test_reports';
import { reportToSentry } from './components/graph/utils';
@@ -59,58 +56,6 @@ const createLegacyPipelinesDetailApp = (mediator) => {
});
};
-const createLegacyPipelineHeaderApp = (mediator) => {
- if (!document.querySelector(SELECTORS.PIPELINE_HEADER)) {
- return;
- }
- // eslint-disable-next-line no-new
- new Vue({
- el: SELECTORS.PIPELINE_HEADER,
- components: {
- legacyPipelineHeader,
- },
- data() {
- return {
- mediator,
- };
- },
- created() {
- eventHub.$on('headerPostAction', this.postAction);
- eventHub.$on('headerDeleteAction', this.deleteAction);
- },
- beforeDestroy() {
- eventHub.$off('headerPostAction', this.postAction);
- eventHub.$off('headerDeleteAction', this.deleteAction);
- },
- errorCaptured(err, _vm, info) {
- reportToSentry('pipeline_details_bundle_legacy', `error: ${err}, info: ${info}`);
- },
- methods: {
- postAction(path) {
- this.mediator.service
- .postAction(path)
- .then(() => this.mediator.refreshPipeline())
- .catch(() => Flash(__('An error occurred while making the request.')));
- },
- deleteAction(path) {
- this.mediator.stopPipelinePoll();
- this.mediator.service
- .deleteAction(path)
- .then(({ request }) => redirectTo(setUrlFragment(request.responseURL, 'delete_success')))
- .catch(() => Flash(__('An error occurred while deleting the pipeline.')));
- },
- },
- render(createElement) {
- return createElement('legacy-pipeline-header', {
- props: {
- isLoading: this.mediator.state.isLoading,
- pipeline: this.mediator.store.state.pipeline,
- },
- });
- },
- });
-};
-
const createTestDetails = () => {
const el = document.querySelector(SELECTORS.PIPELINE_TESTS);
const { summaryEndpoint, suiteEndpoint } = el?.dataset || {};
@@ -136,22 +81,12 @@ export default async function () {
createTestDetails();
createDagApp();
- const { dataset } = document.querySelector(SELECTORS.PIPELINE_DETAILS);
- let mediator;
+ const canShowNewPipelineDetails =
+ gon.features.graphqlPipelineDetails || gon.features.graphqlPipelineDetailsUsers;
- if (!gon.features.graphqlPipelineHeader || !gon.features.graphqlPipelineDetails) {
- try {
- const { default: PipelinesMediator } = await import(
- /* webpackChunkName: 'PipelinesMediator' */ './pipeline_details_mediator'
- );
- mediator = new PipelinesMediator({ endpoint: dataset.endpoint });
- mediator.fetchPipeline();
- } catch {
- Flash(__('An error occurred while loading the pipeline.'));
- }
- }
+ const { dataset } = document.querySelector(SELECTORS.PIPELINE_DETAILS);
- if (gon.features.graphqlPipelineDetails) {
+ if (canShowNewPipelineDetails) {
try {
const { createPipelinesDetailApp } = await import(
/* webpackChunkName: 'createPipelinesDetailApp' */ './pipeline_details_graph'
@@ -163,19 +98,21 @@ export default async function () {
Flash(__('An error occurred while loading the pipeline.'));
}
} else {
+ const { default: PipelinesMediator } = await import(
+ /* webpackChunkName: 'PipelinesMediator' */ './pipeline_details_mediator'
+ );
+ const mediator = new PipelinesMediator({ endpoint: dataset.endpoint });
+ mediator.fetchPipeline();
+
createLegacyPipelinesDetailApp(mediator);
}
- if (gon.features.graphqlPipelineHeader) {
- try {
- const { createPipelineHeaderApp } = await import(
- /* webpackChunkName: 'createPipelineHeaderApp' */ './pipeline_details_header'
- );
- createPipelineHeaderApp(SELECTORS.PIPELINE_HEADER);
- } catch {
- Flash(__('An error occurred while loading a section of this page.'));
- }
- } else {
- createLegacyPipelineHeaderApp(mediator);
+ try {
+ const { createPipelineHeaderApp } = await import(
+ /* webpackChunkName: 'createPipelineHeaderApp' */ './pipeline_details_header'
+ );
+ createPipelineHeaderApp(SELECTORS.PIPELINE_HEADER);
+ } catch {
+ Flash(__('An error occurred while loading a section of this page.'));
}
}
diff --git a/app/assets/javascripts/pipelines/pipeline_details_dag.js b/app/assets/javascripts/pipelines/pipeline_details_dag.js
index d37c72a4f2a..4ee0ad462d2 100644
--- a/app/assets/javascripts/pipelines/pipeline_details_dag.js
+++ b/app/assets/javascripts/pipelines/pipeline_details_dag.js
@@ -12,7 +12,7 @@ const apolloProvider = new VueApollo({
const createDagApp = () => {
const el = document.querySelector('#js-pipeline-dag-vue');
- if (!window.gon?.features?.dagPipelineTab || !el) {
+ if (!el) {
return;
}
diff --git a/app/assets/javascripts/pipelines/pipeline_details_mediator.js b/app/assets/javascripts/pipelines/pipeline_details_mediator.js
index 74c5fc45644..474dc828e5e 100644
--- a/app/assets/javascripts/pipelines/pipeline_details_mediator.js
+++ b/app/assets/javascripts/pipelines/pipeline_details_mediator.js
@@ -1,8 +1,8 @@
import Visibility from 'visibilityjs';
-import PipelineStore from './stores/pipeline_store';
import { deprecatedCreateFlash as Flash } from '../flash';
import Poll from '../lib/utils/poll';
import { __ } from '../locale';
+import PipelineStore from './stores/pipeline_store';
import PipelineService from './services/pipeline_service';
export default class pipelinesMediator {
diff --git a/app/assets/javascripts/pipelines/services/pipelines_service.js b/app/assets/javascripts/pipelines/services/pipelines_service.js
index 0b06bcf243a..523ca13b6c3 100644
--- a/app/assets/javascripts/pipelines/services/pipelines_service.js
+++ b/app/assets/javascripts/pipelines/services/pipelines_service.js
@@ -1,5 +1,5 @@
-import axios from '../../lib/utils/axios_utils';
import Api from '~/api';
+import axios from '../../lib/utils/axios_utils';
import { validateParams } from '../utils';
export default class PipelinesService {
diff --git a/app/assets/javascripts/pipelines/stores/test_reports/actions.js b/app/assets/javascripts/pipelines/stores/test_reports/actions.js
index 3c664457756..3512734e528 100644
--- a/app/assets/javascripts/pipelines/stores/test_reports/actions.js
+++ b/app/assets/javascripts/pipelines/stores/test_reports/actions.js
@@ -1,7 +1,7 @@
import axios from '~/lib/utils/axios_utils';
-import * as types from './mutation_types';
import { deprecatedCreateFlash as createFlash } from '~/flash';
import { s__ } from '~/locale';
+import * as types from './mutation_types';
export const fetchSummary = ({ state, commit, dispatch }) => {
dispatch('toggleLoading');
@@ -28,16 +28,12 @@ export const fetchTestSuite = ({ state, commit, dispatch }, index) => {
dispatch('toggleLoading');
- const { name = '', build_ids = [] } = state.testReports?.test_suites?.[index] || {};
+ const { build_ids = [] } = state.testReports?.test_suites?.[index] || {};
// Replacing `/:suite_name.json` with the name of the suite. Including the extra characters
// to ensure that we replace exactly the template part of the URL string
- const endpoint = state.suiteEndpoint?.replace(
- '/:suite_name.json',
- `/${encodeURIComponent(name)}.json`,
- );
return axios
- .get(endpoint, { params: { build_ids } })
+ .get(state.suiteEndpoint, { params: { build_ids } })
.then(({ data }) => commit(types.SET_SUITE, { suite: data, index }))
.catch(() => {
createFlash(s__('TestReports|There was an error fetching the test suite.'));
diff --git a/app/assets/javascripts/pipelines/stores/test_reports/utils.js b/app/assets/javascripts/pipelines/stores/test_reports/utils.js
index 5c1f27b166a..8d1a941058c 100644
--- a/app/assets/javascripts/pipelines/stores/test_reports/utils.js
+++ b/app/assets/javascripts/pipelines/stores/test_reports/utils.js
@@ -4,16 +4,16 @@ import { TestStatus } from '../../constants';
export function iconForTestStatus(status) {
switch (status) {
case TestStatus.SUCCESS:
- return 'status_success_borderless';
+ return 'status_success';
case TestStatus.FAILED:
- return 'status_failed_borderless';
+ return 'status_failed';
case TestStatus.ERROR:
- return 'status_warning_borderless';
+ return 'status_warning';
case TestStatus.SKIPPED:
- return 'status_skipped_borderless';
+ return 'status_skipped';
case TestStatus.UNKNOWN:
default:
- return 'status_notfound_borderless';
+ return 'status_notfound';
}
}
diff --git a/app/assets/javascripts/pipelines/utils.js b/app/assets/javascripts/pipelines/utils.js
index 50bb23b7e63..23046586de7 100644
--- a/app/assets/javascripts/pipelines/utils.js
+++ b/app/assets/javascripts/pipelines/utils.js
@@ -49,10 +49,10 @@ export const generateJobNeedsDict = (jobs = {}) => {
// to the list of `needs` to ensure we can properly reference it.
const group = jobs[job];
if (group.size > 1) {
- return [job, group.name, ...newNeeds];
+ return [job, group.name, newNeeds];
}
- return [job, ...newNeeds];
+ return [job, newNeeds];
})
.flat(Infinity);
};