summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/pipelines/components/header_component.vue
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-10-21 07:08:36 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-10-21 07:08:36 +0000
commit48aff82709769b098321c738f3444b9bdaa694c6 (patch)
treee00c7c43e2d9b603a5a6af576b1685e400410dee /app/assets/javascripts/pipelines/components/header_component.vue
parent879f5329ee916a948223f8f43d77fba4da6cd028 (diff)
downloadgitlab-ce-48aff82709769b098321c738f3444b9bdaa694c6.tar.gz
Add latest changes from gitlab-org/gitlab@13-5-stable-eev13.5.0-rc42
Diffstat (limited to 'app/assets/javascripts/pipelines/components/header_component.vue')
-rw-r--r--app/assets/javascripts/pipelines/components/header_component.vue166
1 files changed, 127 insertions, 39 deletions
diff --git a/app/assets/javascripts/pipelines/components/header_component.vue b/app/assets/javascripts/pipelines/components/header_component.vue
index c7b72be36ad..b26f28fa6af 100644
--- a/app/assets/javascripts/pipelines/components/header_component.vue
+++ b/app/assets/javascripts/pipelines/components/header_component.vue
@@ -1,8 +1,11 @@
<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 { GlAlert, GlButton, GlLoadingIcon, GlModal, GlModalDirective } from '@gitlab/ui';
import { __ } from '~/locale';
+import axios from '~/lib/utils/axios_utils';
+import ciHeader from '~/vue_shared/components/header_ci_component.vue';
+import { setUrlFragment, redirectTo } from '~/lib/utils/url_utility';
+import getPipelineQuery from '../graphql/queries/get_pipeline_header_data.query.graphql';
+import { LOAD_FAILURE, POST_FAILURE, DELETE_FAILURE, DEFAULT } from '../constants';
const DELETE_MODAL_ID = 'pipeline-delete-modal';
@@ -10,57 +13,143 @@ export default {
name: 'PipelineHeaderSection',
components: {
ciHeader,
+ GlAlert,
+ GlButton,
GlLoadingIcon,
GlModal,
- GlButton,
},
directives: {
GlModal: GlModalDirective,
},
- props: {
- pipeline: {
- type: Object,
- required: true,
+ errorTexts: {
+ [LOAD_FAILURE]: __('We are currently unable to fetch data for the pipeline header.'),
+ [POST_FAILURE]: __('An error occurred while making the request.'),
+ [DELETE_FAILURE]: __('An error occurred while deleting the pipeline.'),
+ [DEFAULT]: __('An unknown error occurred.'),
+ },
+ inject: {
+ // Receive `cancel`, `delete`, `fullProject` and `retry`
+ paths: {
+ default: {},
+ },
+ pipelineId: {
+ default: '',
},
- isLoading: {
- type: Boolean,
- required: true,
+ pipelineIid: {
+ default: '',
+ },
+ },
+ apollo: {
+ pipeline: {
+ query: getPipelineQuery,
+ variables() {
+ return {
+ fullPath: this.paths.fullProject,
+ iid: this.pipelineIid,
+ };
+ },
+ update: data => data.project.pipeline,
+ error() {
+ this.reportFailure(LOAD_FAILURE);
+ },
+ pollInterval: 10000,
+ watchLoading(isLoading) {
+ if (!isLoading) {
+ // To ensure apollo has updated the cache,
+ // we only remove the loading state in sync with GraphQL
+ this.isCanceling = false;
+ this.isRetrying = false;
+ }
+ },
},
},
data() {
return {
+ pipeline: null,
+ failureType: null,
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.',
);
},
+ hasError() {
+ return this.failureType;
+ },
+ hasPipelineData() {
+ return Boolean(this.pipeline);
+ },
+ isLoadingInitialQuery() {
+ return this.$apollo.queries.pipeline.loading && !this.hasPipelineData;
+ },
+ status() {
+ return this.pipeline?.status;
+ },
+ shouldRenderContent() {
+ return !this.isLoadingInitialQuery && this.hasPipelineData;
+ },
+ failure() {
+ switch (this.failureType) {
+ case LOAD_FAILURE:
+ return {
+ text: this.$options.errorTexts[LOAD_FAILURE],
+ variant: 'danger',
+ };
+ case POST_FAILURE:
+ return {
+ text: this.$options.errorTexts[POST_FAILURE],
+ variant: 'danger',
+ };
+ case DELETE_FAILURE:
+ return {
+ text: this.$options.errorTexts[DELETE_FAILURE],
+ variant: 'danger',
+ };
+ default:
+ return {
+ text: this.$options.errorTexts[DEFAULT],
+ variant: 'danger',
+ };
+ }
+ },
},
-
methods: {
- cancelPipeline() {
+ reportFailure(errorType) {
+ this.failureType = errorType;
+ },
+ async postAction(path) {
+ try {
+ await axios.post(path);
+ this.$apollo.queries.pipeline.refetch();
+ } catch {
+ this.reportFailure(POST_FAILURE);
+ }
+ },
+ async cancelPipeline() {
this.isCanceling = true;
- eventHub.$emit('headerPostAction', this.pipeline.cancel_path);
+ this.postAction(this.paths.cancel);
},
- retryPipeline() {
+ async retryPipeline() {
this.isRetrying = true;
- eventHub.$emit('headerPostAction', this.pipeline.retry_path);
+ this.postAction(this.paths.retry);
},
- deletePipeline() {
+ async deletePipeline() {
this.isDeleting = true;
- eventHub.$emit('headerDeleteAction', this.pipeline.delete_path);
+ this.$apollo.queries.pipeline.stopPolling();
+
+ try {
+ const { request } = await axios.delete(this.paths.delete);
+ redirectTo(setUrlFragment(request.responseURL, 'delete_success'));
+ } catch {
+ this.$apollo.queries.pipeline.startPolling();
+ this.reportFailure(DELETE_FAILURE);
+ this.isDeleting = false;
+ }
},
},
DELETE_MODAL_ID,
@@ -68,54 +157,53 @@ export default {
</script>
<template>
<div class="pipeline-header-container">
+ <gl-alert v-if="hasError" :variant="failure.variant">{{ failure.text }}</gl-alert>
<ci-header
v-if="shouldRenderContent"
- :status="status"
- :item-id="pipeline.id"
- :time="pipeline.created_at"
+ :status="pipeline.detailedStatus"
+ :time="pipeline.createdAt"
:user="pipeline.user"
+ :item-id="Number(pipelineId)"
item-name="Pipeline"
>
<gl-button
- v-if="pipeline.retry_path"
+ v-if="pipeline.retryable"
:loading="isRetrying"
:disabled="isRetrying"
- data-testid="retryButton"
category="secondary"
variant="info"
+ data-testid="retryPipeline"
+ class="js-retry-button"
@click="retryPipeline()"
>
{{ __('Retry') }}
</gl-button>
<gl-button
- v-if="pipeline.cancel_path"
+ v-if="pipeline.cancelable"
:loading="isCanceling"
:disabled="isCanceling"
- data-testid="cancelPipeline"
- class="gl-ml-3"
- category="primary"
variant="danger"
+ data-testid="cancelPipeline"
@click="cancelPipeline()"
>
{{ __('Cancel running') }}
</gl-button>
<gl-button
- v-if="pipeline.delete_path"
+ v-if="pipeline.userPermissions.destroyPipeline"
v-gl-modal="$options.DELETE_MODAL_ID"
:loading="isDeleting"
:disabled="isDeleting"
- data-testid="deletePipeline"
class="gl-ml-3"
- category="secondary"
variant="danger"
+ category="secondary"
+ data-testid="deletePipeline"
>
{{ __('Delete') }}
</gl-button>
</ci-header>
-
- <gl-loading-icon v-if="isLoading" size="lg" class="gl-mt-3 gl-mb-3" />
+ <gl-loading-icon v-if="isLoadingInitialQuery" size="lg" class="gl-mt-3 gl-mb-3" />
<gl-modal
:modal-id="$options.DELETE_MODAL_ID"