summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/pipelines
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-08-18 08:17:02 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-08-18 08:17:02 +0000
commitb39512ed755239198a9c294b6a45e65c05900235 (patch)
treed234a3efade1de67c46b9e5a38ce813627726aa7 /app/assets/javascripts/pipelines
parentd31474cf3b17ece37939d20082b07f6657cc79a9 (diff)
downloadgitlab-ce-b39512ed755239198a9c294b6a45e65c05900235.tar.gz
Add latest changes from gitlab-org/gitlab@15-3-stable-eev15.3.0-rc42
Diffstat (limited to 'app/assets/javascripts/pipelines')
-rw-r--r--app/assets/javascripts/pipelines/components/graph/job_group_dropdown.vue5
-rw-r--r--app/assets/javascripts/pipelines/components/graph/job_item.vue3
-rw-r--r--app/assets/javascripts/pipelines/components/performance_insights_modal.vue9
-rw-r--r--app/assets/javascripts/pipelines/components/pipeline_tabs.vue18
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/empty_state/ci_templates.vue14
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipeline_multi_actions.vue40
-rw-r--r--app/assets/javascripts/pipelines/components/test_reports/test_reports.vue26
-rw-r--r--app/assets/javascripts/pipelines/components/test_reports/test_suite_table.vue16
-rw-r--r--app/assets/javascripts/pipelines/components/test_reports/test_summary.vue55
-rw-r--r--app/assets/javascripts/pipelines/components/test_reports/test_summary_table.vue54
-rw-r--r--app/assets/javascripts/pipelines/constants.js2
-rw-r--r--app/assets/javascripts/pipelines/mixins/pipelines_mixin.js13
-rw-r--r--app/assets/javascripts/pipelines/pipeline_tabs.js33
-rw-r--r--app/assets/javascripts/pipelines/stores/test_reports/actions.js1
14 files changed, 176 insertions, 113 deletions
diff --git a/app/assets/javascripts/pipelines/components/graph/job_group_dropdown.vue b/app/assets/javascripts/pipelines/components/graph/job_group_dropdown.vue
index 795ba91a164..8d764fad0c5 100644
--- a/app/assets/javascripts/pipelines/components/graph/job_group_dropdown.vue
+++ b/app/assets/javascripts/pipelines/components/graph/job_group_dropdown.vue
@@ -46,6 +46,9 @@ export default {
const { name, status } = this.group;
return `${name} - ${status.label}`;
},
+ jobGroupClasses() {
+ return [this.cssClassJobName, `job-${this.group.status.group}`];
+ },
},
errorCaptured(err, _vm, info) {
reportToSentry('job_group_dropdown', `error: ${err}, info: ${info}`);
@@ -68,7 +71,7 @@ export default {
type="button"
data-toggle="dropdown"
data-display="static"
- :class="cssClassJobName"
+ :class="jobGroupClasses"
class="dropdown-menu-toggle gl-pipeline-job-width! gl-pr-4!"
>
<div class="gl-display-flex gl-align-items-stretch gl-justify-content-space-between">
diff --git a/app/assets/javascripts/pipelines/components/graph/job_item.vue b/app/assets/javascripts/pipelines/components/graph/job_item.vue
index 362571930d6..377f21b299f 100644
--- a/app/assets/javascripts/pipelines/components/graph/job_item.vue
+++ b/app/assets/javascripts/pipelines/components/graph/job_item.vue
@@ -200,6 +200,9 @@ export default {
},
{ 'gl-rounded-lg': this.isBridge },
this.cssClassJobName,
+ {
+ [`job-${this.status.group}`]: this.isSingleItem,
+ },
];
},
},
diff --git a/app/assets/javascripts/pipelines/components/performance_insights_modal.vue b/app/assets/javascripts/pipelines/components/performance_insights_modal.vue
index ae6b9186930..fdbf0ca19bc 100644
--- a/app/assets/javascripts/pipelines/components/performance_insights_modal.vue
+++ b/app/assets/javascripts/pipelines/components/performance_insights_modal.vue
@@ -97,13 +97,16 @@ export default {
<gl-loading-icon v-if="$apollo.queries.jobs.loading" size="lg" />
<template v-else>
- <gl-alert v-if="showLimitMessage" class="gl-mb-4" :dismissible="false">
- <p>{{ $options.i18n.insightsLimit }}</p>
+ <gl-alert class="gl-mb-4" :dismissible="false">
+ <p v-if="showLimitMessage" data-testid="limit-alert-text">
+ {{ $options.i18n.insightsLimit }}
+ </p>
<gl-link href="https://gitlab.com/gitlab-org/gitlab/-/issues/365902" class="gl-mt-5">
{{ $options.i18n.feeback }}
</gl-link>
</gl-alert>
- <div class="gl-display-flex gl-justify-content-space-between gl-mb-7">
+
+ <div class="gl-display-flex gl-justify-content-space-between gl-mt-2 gl-mb-7">
<gl-card class="gl-w-half gl-mr-7 gl-text-center">
<template #header>
<span class="gl-font-weight-bold">{{ $options.i18n.queuedCardHeader }}</span>
diff --git a/app/assets/javascripts/pipelines/components/pipeline_tabs.vue b/app/assets/javascripts/pipelines/components/pipeline_tabs.vue
index e1745969649..df59962569e 100644
--- a/app/assets/javascripts/pipelines/components/pipeline_tabs.vue
+++ b/app/assets/javascripts/pipelines/components/pipeline_tabs.vue
@@ -34,7 +34,13 @@ export default {
PipelineGraphWrapper,
TestReports,
},
- inject: ['defaultTabValue', 'failedJobsCount', 'failedJobsSummary', 'totalJobCount'],
+ inject: [
+ 'defaultTabValue',
+ 'failedJobsCount',
+ 'failedJobsSummary',
+ 'totalJobCount',
+ 'testsCount',
+ ],
computed: {
showFailedJobsTab() {
return this.failedJobsCount > 0;
@@ -81,11 +87,11 @@ export default {
</template>
<failed-jobs-app :failed-jobs-summary="failedJobsSummary" />
</gl-tab>
- <gl-tab
- :title="$options.i18n.tabs.testsTitle"
- :active="isActive($options.tabNames.tests)"
- data-testid="tests-tab"
- >
+ <gl-tab :active="isActive($options.tabNames.tests)" data-testid="tests-tab" lazy>
+ <template #title>
+ <span class="gl-mr-2">{{ $options.i18n.tabs.testsTitle }}</span>
+ <gl-badge size="sm" data-testid="tests-counter">{{ testsCount }}</gl-badge>
+ </template>
<test-reports />
</gl-tab>
<slot></slot>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/empty_state/ci_templates.vue b/app/assets/javascripts/pipelines/components/pipelines_list/empty_state/ci_templates.vue
index 64d4414eb94..439dc0eb253 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/empty_state/ci_templates.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/empty_state/ci_templates.vue
@@ -32,9 +32,10 @@ export default {
.map(({ name, logo, title }) => {
return {
name: title || name,
+ description: sprintf(this.$options.i18n.description, { name: title || name }),
+ isPng: logo.endsWith('png'),
logo,
link: mergeUrlParams({ template: name }, this.pipelineEditorPath),
- description: sprintf(this.$options.i18n.description, { name: title || name }),
};
});
@@ -48,6 +49,9 @@ export default {
label: template,
});
},
+ logoStyle(template) {
+ return template.isPng ? { objectFit: 'contain' } : '';
+ },
},
i18n: {
description: s__(
@@ -66,11 +70,13 @@ export default {
>
<div class="gl-display-flex gl-flex-direction-row gl-align-items-center">
<gl-avatar
- :src="template.logo"
- :size="48"
+ :alt="template.name"
class="gl-mr-5 gl-bg-white dark-mode-override"
+ :class="{ 'gl-p-2': template.isPng }"
+ :style="logoStyle(template)"
:shape="$options.AVATAR_SHAPE_OPTION_RECT"
- :alt="template.name"
+ :size="48"
+ :src="template.logo"
data-testid="template-logo"
/>
<div class="gl-flex-direction-row">
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_multi_actions.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_multi_actions.vue
index 9725e882d5e..05a1ceface3 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_multi_actions.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_multi_actions.vue
@@ -3,16 +3,16 @@ import {
GlAlert,
GlDropdown,
GlDropdownItem,
- GlDropdownSectionHeader,
+ GlSearchBoxByType,
GlLoadingIcon,
GlTooltipDirective,
} from '@gitlab/ui';
+import fuzzaldrinPlus from 'fuzzaldrin-plus';
import axios from '~/lib/utils/axios_utils';
import { __, s__ } from '~/locale';
export const i18n = {
- artifacts: __('Artifacts'),
- artifactSectionHeader: __('Download artifacts'),
+ downloadArtifacts: __('Download artifacts'),
artifactsFetchErrorMessage: s__('Pipelines|Could not load artifacts.'),
emptyArtifactsMessage: __('No artifacts found'),
};
@@ -26,7 +26,7 @@ export default {
GlAlert,
GlDropdown,
GlDropdownItem,
- GlDropdownSectionHeader,
+ GlSearchBoxByType,
GlLoadingIcon,
},
inject: {
@@ -48,8 +48,16 @@ export default {
artifacts: [],
hasError: false,
isLoading: false,
+ searchQuery: '',
};
},
+ computed: {
+ filteredArtifacts() {
+ return this.searchQuery.length > 0
+ ? fuzzaldrinPlus.filter(this.artifacts, this.searchQuery, { key: 'name' })
+ : this.artifacts;
+ },
+ },
methods: {
fetchArtifacts() {
this.isLoading = true;
@@ -70,27 +78,27 @@ export default {
this.isLoading = false;
});
},
+ handleDropdownShown() {
+ this.$refs.searchInput.focusInput();
+ },
},
};
</script>
<template>
<gl-dropdown
v-gl-tooltip
- :title="$options.i18n.artifacts"
- :text="$options.i18n.artifacts"
- :aria-label="$options.i18n.artifacts"
- icon="ellipsis_v"
+ :title="$options.i18n.downloadArtifacts"
+ :text="$options.i18n.downloadArtifacts"
+ :aria-label="$options.i18n.downloadArtifacts"
+ :header-text="$options.i18n.downloadArtifacts"
+ icon="download"
data-testid="pipeline-multi-actions-dropdown"
right
lazy
text-sr-only
- no-caret
@show.once="fetchArtifacts"
+ @shown="handleDropdownShown"
>
- <gl-dropdown-section-header>{{
- $options.i18n.artifactSectionHeader
- }}</gl-dropdown-section-header>
-
<gl-alert v-if="hasError" variant="danger" :dismissible="false">
{{ $options.i18n.artifactsFetchErrorMessage }}
</gl-alert>
@@ -101,8 +109,12 @@ export default {
{{ $options.i18n.emptyArtifactsMessage }}
</gl-dropdown-item>
+ <template #header>
+ <gl-search-box-by-type v-if="artifacts.length" ref="searchInput" v-model.trim="searchQuery" />
+ </template>
+
<gl-dropdown-item
- v-for="(artifact, i) in artifacts"
+ v-for="(artifact, i) in filteredArtifacts"
:key="i"
:href="artifact.path"
rel="nofollow"
diff --git a/app/assets/javascripts/pipelines/components/test_reports/test_reports.vue b/app/assets/javascripts/pipelines/components/test_reports/test_reports.vue
index 3fb46a4f128..e5666f7a658 100644
--- a/app/assets/javascripts/pipelines/components/test_reports/test_reports.vue
+++ b/app/assets/javascripts/pipelines/components/test_reports/test_reports.vue
@@ -1,6 +1,7 @@
<script>
import { GlLoadingIcon } from '@gitlab/ui';
import { mapActions, mapGetters, mapState } from 'vuex';
+import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import createTestReportsStore from '../../stores/test_reports';
import EmptyState from './empty_state.vue';
import TestSuiteTable from './test_suite_table.vue';
@@ -16,6 +17,7 @@ export default {
TestSummary,
TestSummaryTable,
},
+ mixins: [glFeatureFlagMixin()],
inject: ['blobPath', 'summaryEndpoint', 'suiteEndpoint'],
computed: {
...mapState('testReports', ['isLoading', 'selectedSuiteIndex', 'testReports']),
@@ -29,14 +31,16 @@ export default {
},
},
created() {
- this.$store.registerModule(
- 'testReports',
- createTestReportsStore({
- blobPath: this.blobPath,
- summaryEndpoint: this.summaryEndpoint,
- suiteEndpoint: this.suiteEndpoint,
- }),
- );
+ if (!this.glFeatures.pipelineTabsVue) {
+ this.$store.registerModule(
+ 'testReports',
+ createTestReportsStore({
+ blobPath: this.blobPath,
+ summaryEndpoint: this.summaryEndpoint,
+ suiteEndpoint: this.suiteEndpoint,
+ }),
+ );
+ }
this.fetchSummary();
},
@@ -74,7 +78,7 @@ export default {
<div
v-else-if="!isLoading && showTests"
ref="container"
- class="position-relative"
+ class="gl-relative"
data-testid="tests-detail"
>
<transition
@@ -82,13 +86,13 @@ export default {
@before-enter="beforeEnterTransition"
@after-leave="afterLeaveTransition"
>
- <div v-if="showSuite" key="detail" class="w-100 slide-enter-to-element">
+ <div v-if="showSuite" key="detail" class="gl-w-full slide-enter-to-element">
<test-summary :report="getSelectedSuite" show-back @on-back-click="summaryBackClick" />
<test-suite-table />
</div>
- <div v-else key="summary" class="w-100 slide-enter-from-element">
+ <div v-else key="summary" class="gl-w-full slide-enter-from-element">
<test-summary :report="testReports" />
<test-summary-table @row-click="summaryTableRowClick" />
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 1f438c63fee..7d0f1ba4b5f 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
@@ -80,7 +80,10 @@ export default {
<h4>{{ heading }}</h4>
</div>
</div>
- <div role="row" class="gl-responsive-table-row table-row-header font-weight-bold fgray">
+ <div
+ role="row"
+ class="gl-responsive-table-row table-row-header gl-font-weight-bold gl-fill-gray-700"
+ >
<div role="rowheader" class="table-section section-20">
{{ __('Suite') }}
</div>
@@ -104,7 +107,7 @@ export default {
<div
v-for="(testCase, index) in getSuiteTests"
:key="index"
- class="gl-responsive-table-row rounded align-items-md-start"
+ class="gl-responsive-table-row gl-rounded-base gl-align-items-flex-start"
data-testid="test-case-row"
>
<div class="table-section section-20 section-wrap">
@@ -142,11 +145,8 @@ export default {
<div class="table-section section-10 section-wrap">
<div role="rowheader" class="table-mobile-header">{{ __('Status') }}</div>
- <div class="table-mobile-content text-center">
- <div
- class="ci-status-icon d-flex align-items-center justify-content-end justify-content-md-center"
- :class="`ci-status-icon-${testCase.status}`"
- >
+ <div class="table-mobile-content gl-md-display-flex gl-justify-content-center">
+ <div class="ci-status-icon" :class="`ci-status-icon-${testCase.status}`">
<gl-icon :size="24" :name="testCase.icon" />
</div>
</div>
@@ -156,7 +156,7 @@ export default {
<div role="rowheader" class="table-mobile-header">
{{ __('Duration') }}
</div>
- <div class="table-mobile-content pr-sm-1">
+ <div class="table-mobile-content gl-sm-pr-2">
{{ testCase.formattedTime }}
</div>
</div>
diff --git a/app/assets/javascripts/pipelines/components/test_reports/test_summary.vue b/app/assets/javascripts/pipelines/components/test_reports/test_summary.vue
index 2f5301715c3..6b723ad5481 100644
--- a/app/assets/javascripts/pipelines/components/test_reports/test_summary.vue
+++ b/app/assets/javascripts/pipelines/components/test_reports/test_summary.vue
@@ -65,58 +65,53 @@ export default {
<template>
<div>
- <div class="row">
- <div class="col-12 d-flex gl-mt-3 align-items-center">
- <gl-button
- v-if="showBack"
- size="small"
- class="gl-mr-3 js-back-button"
- icon="chevron-lg-left"
- :aria-label="__('Go back')"
- @click="onBackClick"
- />
+ <div class="gl-w-full gl-display-flex gl-mt-3 gl-align-items-center">
+ <gl-button
+ v-if="showBack"
+ size="small"
+ class="gl-mr-3 js-back-button"
+ icon="chevron-lg-left"
+ :aria-label="__('Go back')"
+ @click="onBackClick"
+ />
- <h4>{{ heading }}</h4>
- </div>
+ <h4>{{ heading }}</h4>
</div>
- <div class="row mt-2">
- <div class="col-4 col-md">
- <span class="js-total-tests">{{
+ <div
+ class="gl-display-flex gl-flex-direction-column gl-md-flex-direction-row gl-w-full gl-mt-3"
+ >
+ <div class="gl-display-flex gl-justify-content-space-between gl-flex-basis-half">
+ <span class="js-total-tests gl-flex-grow-1">{{
sprintf(s__('TestReports|%{count} tests'), { count: report.total_count })
}}</span>
- </div>
- <div class="col-4 col-md text-center text-md-center">
- <span class="js-failed-tests">{{
+ <span class="js-failed-tests gl-flex-grow-1">{{
sprintf(s__('TestReports|%{count} failures'), { count: report.failed_count })
}}</span>
- </div>
- <div class="col-4 col-md text-right text-md-center">
<span class="js-errored-tests">{{
sprintf(s__('TestReports|%{count} errors'), { count: report.error_count })
}}</span>
</div>
-
- <div class="col-6 mt-3 col-md mt-md-0 text-md-center">
- <span class="js-success-rate">{{
+ <div class="gl-display-flex gl-justify-content-space-between gl-flex-grow-1">
+ <div class="gl-display-none gl-md-display-block gl-flex-grow-1"></div>
+ <span class="js-success-rate gl-flex-grow-1">{{
sprintf(s__('TestReports|%{rate}%{sign} success rate'), {
rate: successPercentage,
sign: '%',
})
}}</span>
- </div>
- <div class="col-6 mt-3 col-md mt-md-0 text-right">
<span class="js-duration">{{ formattedDuration }}</span>
</div>
</div>
- <div class="row mt-3">
- <div class="col-12">
- <gl-progress-bar :value="successPercentage" :variant="progressBarVariant" height="10px" />
- </div>
- </div>
+ <gl-progress-bar
+ class="gl-mt-5"
+ :value="successPercentage"
+ :variant="progressBarVariant"
+ height="10px"
+ />
</div>
</template>
diff --git a/app/assets/javascripts/pipelines/components/test_reports/test_summary_table.vue b/app/assets/javascripts/pipelines/components/test_reports/test_summary_table.vue
index 8389c2a5104..7ab48da1a9d 100644
--- a/app/assets/javascripts/pipelines/components/test_reports/test_summary_table.vue
+++ b/app/assets/javascripts/pipelines/components/test_reports/test_summary_table.vue
@@ -34,33 +34,31 @@ export default {
<template>
<div>
- <div class="row gl-mt-3">
- <div class="col-12">
- <h4>{{ heading }}</h4>
- </div>
+ <div class="gl-mt-5">
+ <h4>{{ heading }}</h4>
</div>
- <div v-if="hasSuites" class="test-reports-table gl-mb-3 js-test-suites-table">
- <div role="row" class="gl-responsive-table-row table-row-header font-weight-bold">
- <div role="rowheader" class="table-section section-25 pl-3">
+ <div v-if="hasSuites" class="js-test-suites-table">
+ <div role="row" class="gl-responsive-table-row table-row-header gl-font-weight-bold">
+ <div role="rowheader" class="table-section section-25 gl-pl-5">
{{ __('Job') }}
</div>
<div role="rowheader" class="table-section section-25">
{{ __('Duration') }}
</div>
- <div role="rowheader" class="table-section section-10 text-center">
+ <div role="rowheader" class="table-section section-10 gl-text-center">
{{ __('Failed') }}
</div>
- <div role="rowheader" class="table-section section-10 text-center">
+ <div role="rowheader" class="table-section section-10 gl-text-center">
{{ __('Errors'), }}
</div>
- <div role="rowheader" class="table-section section-10 text-center">
+ <div role="rowheader" class="table-section section-10 gl-text-center">
{{ __('Skipped'), }}
</div>
- <div role="rowheader" class="table-section section-10 text-center">
+ <div role="rowheader" class="table-section section-10 gl-text-center">
{{ __('Passed'), }}
</div>
- <div role="rowheader" class="table-section section-10 pr-3 text-right">
+ <div role="rowheader" class="table-section section-10 gl-pr-5 gl-text-right">
{{ __('Total') }}
</div>
</div>
@@ -69,17 +67,17 @@ export default {
v-for="(testSuite, index) in getTestSuites"
:key="index"
role="row"
- class="gl-responsive-table-row test-reports-summary-row rounded js-suite-row"
+ class="gl-responsive-table-row gl-rounded-base js-suite-row"
:class="{
- 'gl-responsive-table-row-clickable cursor-pointer': !testSuite.suite_error,
+ 'gl-responsive-table-row-clickable gl-cursor-pointer': !testSuite.suite_error,
}"
@click="tableRowClick(index)"
>
<div class="table-section section-25">
- <div role="rowheader" class="table-mobile-header font-weight-bold">
+ <div role="rowheader" class="table-mobile-header gl-font-weight-bold">
{{ __('Suite') }}
</div>
- <div class="table-mobile-content underline cgray pl-3">
+ <div class="table-mobile-content underline gl-text-gray-900 gl-pl-5">
{{ testSuite.name }}
<gl-icon
v-if="testSuite.suite_error"
@@ -93,44 +91,44 @@ export default {
</div>
<div class="table-section section-25">
- <div role="rowheader" class="table-mobile-header font-weight-bold">
+ <div role="rowheader" class="table-mobile-header gl-font-weight-bold">
{{ __('Duration') }}
</div>
- <div class="table-mobile-content text-md-left">
+ <div class="table-mobile-content gl-text-left">
{{ testSuite.formattedTime }}
</div>
</div>
- <div class="table-section section-10 text-center">
- <div role="rowheader" class="table-mobile-header font-weight-bold">
+ <div class="table-section section-10 gl-text-center">
+ <div role="rowheader" class="table-mobile-header gl-font-weight-bold">
{{ __('Failed') }}
</div>
<div class="table-mobile-content">{{ testSuite.failed_count }}</div>
</div>
- <div class="table-section section-10 text-center">
- <div role="rowheader" class="table-mobile-header font-weight-bold">
+ <div class="table-section section-10 gl-text-center">
+ <div role="rowheader" class="table-mobile-header gl-font-weight-bold">
{{ __('Errors') }}
</div>
<div class="table-mobile-content">{{ testSuite.error_count }}</div>
</div>
- <div class="table-section section-10 text-center">
- <div role="rowheader" class="table-mobile-header font-weight-bold">
+ <div class="table-section section-10 gl-text-center">
+ <div role="rowheader" class="table-mobile-header gl-font-weight-bold">
{{ __('Skipped') }}
</div>
<div class="table-mobile-content">{{ testSuite.skipped_count }}</div>
</div>
- <div class="table-section section-10 text-center">
- <div role="rowheader" class="table-mobile-header font-weight-bold">
+ <div class="table-section section-10 gl-text-center">
+ <div role="rowheader" class="table-mobile-header gl-font-weight-bold">
{{ __('Passed') }}
</div>
<div class="table-mobile-content">{{ testSuite.success_count }}</div>
</div>
- <div class="table-section section-10 text-right pr-md-3">
- <div role="rowheader" class="table-mobile-header font-weight-bold">
+ <div class="table-section section-10 gl-text-right pr-md-3">
+ <div role="rowheader" class="table-mobile-header gl-font-weight-bold">
{{ __('Total') }}
</div>
<div class="table-mobile-content">{{ testSuite.total_count }}</div>
diff --git a/app/assets/javascripts/pipelines/constants.js b/app/assets/javascripts/pipelines/constants.js
index 2e825016c91..7b38f870cb6 100644
--- a/app/assets/javascripts/pipelines/constants.js
+++ b/app/assets/javascripts/pipelines/constants.js
@@ -83,7 +83,7 @@ export const PipelineKeyOptions = [
export const TOAST_MESSAGE = s__('Pipeline|Creating pipeline.');
-export const BUTTON_TOOLTIP_RETRY = __('Retry failed jobs');
+export const BUTTON_TOOLTIP_RETRY = __('Retry all failed or cancelled jobs');
export const BUTTON_TOOLTIP_CANCEL = __('Cancel');
export const DEFAULT_FIELDS = [
diff --git a/app/assets/javascripts/pipelines/mixins/pipelines_mixin.js b/app/assets/javascripts/pipelines/mixins/pipelines_mixin.js
index c4f7665c91d..e8e49cc652e 100644
--- a/app/assets/javascripts/pipelines/mixins/pipelines_mixin.js
+++ b/app/assets/javascripts/pipelines/mixins/pipelines_mixin.js
@@ -1,5 +1,6 @@
import Visibility from 'visibilityjs';
-import createFlash from '~/flash';
+import createFlash, { createAlert } from '~/flash';
+import { helpPagePath } from '~/helpers/help_page_helper';
import { historyPushState, buildUrlWithCurrentLocation } from '~/lib/utils/common_utils';
import httpStatusCodes from '~/lib/utils/http_status';
import Poll from '~/lib/utils/poll';
@@ -198,18 +199,20 @@ export default {
})
.catch((e) => {
const unauthorized = e.response.status === httpStatusCodes.UNAUTHORIZED;
- const badRequest = e.response.status === httpStatusCodes.BAD_REQUEST;
-
let errorMessage = __(
'An error occurred while trying to run a new pipeline for this merge request.',
);
- if (unauthorized || badRequest) {
+ if (unauthorized) {
errorMessage = __('You do not have permission to run a pipeline on this branch.');
}
- createFlash({
+ createAlert({
message: errorMessage,
+ primaryButton: {
+ text: __('Learn more'),
+ link: helpPagePath('ci/pipelines/merge_request_pipelines.md'),
+ },
});
})
.finally(() => this.store.toggleIsRunningPipeline(false));
diff --git a/app/assets/javascripts/pipelines/pipeline_tabs.js b/app/assets/javascripts/pipelines/pipeline_tabs.js
index c0e769e2485..7051d356089 100644
--- a/app/assets/javascripts/pipelines/pipeline_tabs.js
+++ b/app/assets/javascripts/pipelines/pipeline_tabs.js
@@ -5,6 +5,7 @@ import PipelineTabs from 'ee_else_ce/pipelines/components/pipeline_tabs.vue';
import { removeParams, updateHistory } from '~/lib/utils/url_utility';
import { TAB_QUERY_PARAM } from '~/pipelines/constants';
import { parseBoolean } from '~/lib/utils/common_utils';
+import createTestReportsStore from './stores/test_reports';
import { getPipelineDefaultTab, reportToSentry } from './utils';
Vue.use(VueApollo);
@@ -29,6 +30,17 @@ export const createAppOptions = (selector, apolloProvider) => {
pipelineIid,
pipelineProjectPath,
totalJobCount,
+ licenseManagementApiUrl,
+ licenseManagementSettingsPath,
+ licensesApiPath,
+ canManageLicenses,
+ summaryEndpoint,
+ suiteEndpoint,
+ blobPath,
+ hasTestReport,
+ emptyStateImagePath,
+ artifactsExpiredImagePath,
+ testsCount,
} = dataset;
const defaultTabValue = getPipelineDefaultTab(window.location.href);
@@ -39,7 +51,15 @@ export const createAppOptions = (selector, apolloProvider) => {
PipelineTabs,
},
apolloProvider,
- store: new Vuex.Store(),
+ store: new Vuex.Store({
+ modules: {
+ testReports: createTestReportsStore({
+ blobPath,
+ summaryEndpoint,
+ suiteEndpoint,
+ }),
+ },
+ }),
provide: {
canGenerateCodequalityReports: parseBoolean(canGenerateCodequalityReports),
codequalityReportDownloadPath,
@@ -54,6 +74,17 @@ export const createAppOptions = (selector, apolloProvider) => {
pipelineIid,
pipelineProjectPath,
totalJobCount,
+ licenseManagementApiUrl,
+ licenseManagementSettingsPath,
+ licensesApiPath,
+ canManageLicenses: parseBoolean(canManageLicenses),
+ summaryEndpoint,
+ suiteEndpoint,
+ blobPath,
+ hasTestReport,
+ emptyStateImagePath,
+ artifactsExpiredImagePath,
+ testsCount,
},
errorCaptured(err, _vm, info) {
reportToSentry('pipeline_tabs', `error: ${err}, info: ${info}`);
diff --git a/app/assets/javascripts/pipelines/stores/test_reports/actions.js b/app/assets/javascripts/pipelines/stores/test_reports/actions.js
index f0556f3d12e..b785fd1753c 100644
--- a/app/assets/javascripts/pipelines/stores/test_reports/actions.js
+++ b/app/assets/javascripts/pipelines/stores/test_reports/actions.js
@@ -30,7 +30,6 @@ export const fetchTestSuite = ({ state, commit, dispatch }, index) => {
dispatch('toggleLoading');
- // eslint-disable-next-line camelcase
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