2017-09-10 17:25:29 +05:30
< script >
2022-04-04 11:22:00 +05:30
import {
GlAlert ,
GlButton ,
GlLoadingIcon ,
GlModal ,
GlModalDirective ,
GlTooltipDirective ,
} from '@gitlab/ui' ;
2023-07-09 08:55:56 +05:30
import { setUrlFragment , redirectTo } from '~/lib/utils/url_utility' ; // eslint-disable-line import/no-deprecated
2019-09-30 21:07:59 +05:30
import { _ _ } from '~/locale' ;
2022-10-11 01:57:18 +05:30
import CiHeader from '~/vue_shared/components/header_ci_component.vue' ;
2022-04-04 11:22:00 +05:30
import {
LOAD _FAILURE ,
POST _FAILURE ,
DELETE _FAILURE ,
DEFAULT ,
BUTTON _TOOLTIP _RETRY ,
2023-07-09 08:55:56 +05:30
BUTTON _TOOLTIP _CANCEL ,
2022-04-04 11:22:00 +05:30
} from '../constants' ;
2021-03-11 19:13:27 +05:30
import cancelPipelineMutation from '../graphql/mutations/cancel_pipeline.mutation.graphql' ;
2021-01-29 00:20:46 +05:30
import deletePipelineMutation from '../graphql/mutations/delete_pipeline.mutation.graphql' ;
import retryPipelineMutation from '../graphql/mutations/retry_pipeline.mutation.graphql' ;
2021-03-11 19:13:27 +05:30
import getPipelineQuery from '../graphql/queries/get_pipeline_header_data.query.graphql' ;
2021-04-29 21:17:54 +05:30
import { getQueryHeaders } from './graph/utils' ;
2017-09-10 17:25:29 +05:30
2020-03-13 15:44:24 +05:30
const DELETE _MODAL _ID = 'pipeline-delete-modal' ;
2021-01-29 00:20:46 +05:30
const POLL _INTERVAL = 10000 ;
2020-03-13 15:44:24 +05:30
2018-11-08 19:23:39 +05:30
export default {
name : 'PipelineHeaderSection' ,
2022-04-04 11:22:00 +05:30
BUTTON _TOOLTIP _RETRY ,
2023-07-09 08:55:56 +05:30
BUTTON _TOOLTIP _CANCEL ,
2021-01-29 00:20:46 +05:30
pipelineCancel : 'pipelineCancel' ,
pipelineRetry : 'pipelineRetry' ,
finishedStatuses : [ 'FAILED' , 'SUCCESS' , 'CANCELED' ] ,
2018-11-08 19:23:39 +05:30
components : {
2022-10-11 01:57:18 +05:30
CiHeader ,
2021-01-03 14:25:43 +05:30
GlAlert ,
GlButton ,
2018-12-13 13:39:08 +05:30
GlLoadingIcon ,
2020-03-13 15:44:24 +05:30
GlModal ,
} ,
directives : {
GlModal : GlModalDirective ,
2022-04-04 11:22:00 +05:30
GlTooltip : GlTooltipDirective ,
2018-11-08 19:23:39 +05:30
} ,
2021-01-03 14:25:43 +05:30
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 : {
2021-04-29 21:17:54 +05:30
graphqlResourceEtag : {
default : '' ,
} ,
2021-01-03 14:25:43 +05:30
paths : {
default : { } ,
} ,
pipelineId : {
default : '' ,
2017-09-10 17:25:29 +05:30
} ,
2021-01-03 14:25:43 +05:30
pipelineIid : {
default : '' ,
} ,
} ,
2022-08-13 15:12:31 +05:30
modal : {
id : DELETE _MODAL _ID ,
actionPrimary : {
text : _ _ ( 'Delete pipeline' ) ,
attributes : {
variant : 'danger' ,
} ,
} ,
actionCancel : {
text : _ _ ( 'Cancel' ) ,
} ,
} ,
2021-01-03 14:25:43 +05:30
apollo : {
pipeline : {
2021-04-29 21:17:54 +05:30
context ( ) {
return getQueryHeaders ( this . graphqlResourceEtag ) ;
} ,
2021-01-03 14:25:43 +05:30
query : getPipelineQuery ,
variables ( ) {
return {
fullPath : this . paths . fullProject ,
iid : this . pipelineIid ,
} ;
} ,
2021-03-08 18:12:59 +05:30
update : ( data ) => data . project . pipeline ,
2021-01-03 14:25:43 +05:30
error ( ) {
this . reportFailure ( LOAD _FAILURE ) ;
} ,
2021-01-29 00:20:46 +05:30
pollInterval : POLL _INTERVAL ,
2021-01-03 14:25:43 +05:30
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 ;
}
} ,
2017-09-10 17:25:29 +05:30
} ,
2018-11-08 19:23:39 +05:30
} ,
data ( ) {
return {
2021-01-03 14:25:43 +05:30
pipeline : null ,
2022-07-16 23:28:13 +05:30
failureMessages : [ ] ,
2021-01-03 14:25:43 +05:30
failureType : null ,
2020-03-13 15:44:24 +05:30
isCanceling : false ,
isRetrying : false ,
isDeleting : false ,
2018-11-08 19:23:39 +05:30
} ;
} ,
computed : {
2020-03-13 15:44:24 +05:30
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.' ,
) ;
2018-03-17 18:26:18 +05:30
} ,
2021-01-03 14:25:43 +05:30
hasError ( ) {
return this . failureType ;
} ,
hasPipelineData ( ) {
return Boolean ( this . pipeline ) ;
} ,
isLoadingInitialQuery ( ) {
return this . $apollo . queries . pipeline . loading && ! this . hasPipelineData ;
} ,
status ( ) {
return this . pipeline ? . status ;
} ,
2021-01-29 00:20:46 +05:30
isFinished ( ) {
return this . $options . finishedStatuses . includes ( this . status ) ;
} ,
2021-01-03 14:25:43 +05:30
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' ,
} ;
}
} ,
2021-09-04 01:27:46 +05:30
canRetryPipeline ( ) {
const { retryable , userPermissions } = this . pipeline ;
return retryable && userPermissions . updatePipeline ;
} ,
canCancelPipeline ( ) {
const { cancelable , userPermissions } = this . pipeline ;
return cancelable && userPermissions . updatePipeline ;
} ,
2018-11-08 19:23:39 +05:30
} ,
methods : {
2022-07-16 23:28:13 +05:30
reportFailure ( errorType , errorMessages = [ ] ) {
2021-01-03 14:25:43 +05:30
this . failureType = errorType ;
2022-07-16 23:28:13 +05:30
this . failureMessages = errorMessages ;
2021-01-03 14:25:43 +05:30
} ,
2021-01-29 00:20:46 +05:30
async postPipelineAction ( name , mutation ) {
2021-01-03 14:25:43 +05:30
try {
2021-01-29 00:20:46 +05:30
const {
data : {
[ name ] : { errors } ,
} ,
} = await this . $apollo . mutate ( {
mutation ,
variables : { id : this . pipeline . id } ,
} ) ;
if ( errors . length > 0 ) {
2022-05-07 20:08:51 +05:30
this . isRetrying = false ;
2022-07-16 23:28:13 +05:30
this . reportFailure ( POST _FAILURE , errors ) ;
2021-01-29 00:20:46 +05:30
} else {
await this . $apollo . queries . pipeline . refetch ( ) ;
if ( ! this . isFinished ) {
this . $apollo . queries . pipeline . startPolling ( POLL _INTERVAL ) ;
}
}
2021-01-03 14:25:43 +05:30
} catch {
2022-05-07 20:08:51 +05:30
this . isRetrying = false ;
2021-01-03 14:25:43 +05:30
this . reportFailure ( POST _FAILURE ) ;
}
} ,
2021-01-29 00:20:46 +05:30
cancelPipeline ( ) {
2020-03-13 15:44:24 +05:30
this . isCanceling = true ;
2021-01-29 00:20:46 +05:30
this . postPipelineAction ( this . $options . pipelineCancel , cancelPipelineMutation ) ;
2018-11-08 19:23:39 +05:30
} ,
2021-01-29 00:20:46 +05:30
retryPipeline ( ) {
2020-03-13 15:44:24 +05:30
this . isRetrying = true ;
2021-01-29 00:20:46 +05:30
this . postPipelineAction ( this . $options . pipelineRetry , retryPipelineMutation ) ;
2020-03-13 15:44:24 +05:30
} ,
2021-01-03 14:25:43 +05:30
async deletePipeline ( ) {
2020-03-13 15:44:24 +05:30
this . isDeleting = true ;
2021-01-03 14:25:43 +05:30
this . $apollo . queries . pipeline . stopPolling ( ) ;
try {
2021-01-29 00:20:46 +05:30
const {
data : {
pipelineDestroy : { errors } ,
} ,
} = await this . $apollo . mutate ( {
mutation : deletePipelineMutation ,
variables : {
id : this . pipeline . id ,
} ,
} ) ;
if ( errors . length > 0 ) {
2022-07-16 23:28:13 +05:30
this . reportFailure ( DELETE _FAILURE , errors ) ;
2021-01-29 00:20:46 +05:30
this . isDeleting = false ;
} else {
2023-07-09 08:55:56 +05:30
redirectTo ( setUrlFragment ( this . paths . pipelinesPath , 'delete_success' ) ) ; // eslint-disable-line import/no-deprecated
2021-01-29 00:20:46 +05:30
}
2021-01-03 14:25:43 +05:30
} catch {
2021-01-29 00:20:46 +05:30
this . $apollo . queries . pipeline . startPolling ( POLL _INTERVAL ) ;
2021-01-03 14:25:43 +05:30
this . reportFailure ( DELETE _FAILURE ) ;
this . isDeleting = false ;
}
2017-09-10 17:25:29 +05:30
} ,
2018-11-08 19:23:39 +05:30
} ,
2020-03-13 15:44:24 +05:30
DELETE _MODAL _ID ,
2018-11-08 19:23:39 +05:30
} ;
2017-09-10 17:25:29 +05:30
< / script >
< template >
2021-10-27 15:23:28 +05:30
< div class = "js-pipeline-header-container" >
2022-07-16 23:28:13 +05:30
< gl-alert v-if ="hasError" :title="failure.text" :variant="failure.variant" :dismissible ="false" >
< div v-for = "(failureMessage, index) in failureMessages" :key="`failure-message-${index}`" >
{ { failureMessage } }
< / div >
< / gl-alert >
2017-09-10 17:25:29 +05:30
< ci-header
v - if = "shouldRenderContent"
2021-01-03 14:25:43 +05:30
: status = "pipeline.detailedStatus"
: time = "pipeline.createdAt"
2017-09-10 17:25:29 +05:30
: user = "pipeline.user"
2021-11-11 11:23:49 +05:30
: item - id = "pipelineId"
2018-11-08 19:23:39 +05:30
item - name = "Pipeline"
2020-03-13 15:44:24 +05:30
>
2020-10-24 23:57:45 +05:30
< gl-button
2021-09-04 01:27:46 +05:30
v - if = "canRetryPipeline"
2022-04-04 11:22:00 +05:30
v - gl - tooltip
: aria - label = "$options.BUTTON_TOOLTIP_RETRY"
: title = "$options.BUTTON_TOOLTIP_RETRY"
2020-03-13 15:44:24 +05:30
: loading = "isRetrying"
: disabled = "isRetrying"
2022-06-21 17:19:12 +05:30
variant = "confirm"
2021-01-03 14:25:43 +05:30
data - testid = "retryPipeline"
class = "js-retry-button"
2020-03-13 15:44:24 +05:30
@ click = "retryPipeline()"
2020-10-24 23:57:45 +05:30
>
{ { _ _ ( 'Retry' ) } }
< / gl-button >
2020-03-13 15:44:24 +05:30
2020-10-24 23:57:45 +05:30
< gl-button
2021-09-04 01:27:46 +05:30
v - if = "canCancelPipeline"
2023-07-09 08:55:56 +05:30
v - gl - tooltip
: aria - label = "$options.BUTTON_TOOLTIP_CANCEL"
: title = "$options.BUTTON_TOOLTIP_CANCEL"
2020-03-13 15:44:24 +05:30
: loading = "isCanceling"
: disabled = "isCanceling"
2022-07-16 23:28:13 +05:30
class = "gl-ml-3"
2020-10-24 23:57:45 +05:30
variant = "danger"
2021-01-03 14:25:43 +05:30
data - testid = "cancelPipeline"
2020-03-13 15:44:24 +05:30
@ click = "cancelPipeline()"
2020-10-24 23:57:45 +05:30
>
2023-07-09 08:55:56 +05:30
{ { _ _ ( 'Cancel pipeline' ) } }
2020-10-24 23:57:45 +05:30
< / gl-button >
2020-03-13 15:44:24 +05:30
2020-10-24 23:57:45 +05:30
< gl-button
2021-01-03 14:25:43 +05:30
v - if = "pipeline.userPermissions.destroyPipeline"
2022-08-13 15:12:31 +05:30
v - gl - modal = "$options.modal.id"
2020-03-13 15:44:24 +05:30
: loading = "isDeleting"
: disabled = "isDeleting"
2020-10-24 23:57:45 +05:30
class = "gl-ml-3"
variant = "danger"
2021-01-03 14:25:43 +05:30
category = "secondary"
data - testid = "deletePipeline"
2020-10-24 23:57:45 +05:30
>
{ { _ _ ( 'Delete' ) } }
< / gl-button >
2020-03-13 15:44:24 +05:30
< / ci-header >
2021-01-03 14:25:43 +05:30
< gl-loading-icon v-if = "isLoadingInitialQuery" size="lg" class="gl-mt-3 gl-mb-3" / >
2020-03-13 15:44:24 +05:30
< gl-modal
2022-08-13 15:12:31 +05:30
: modal - id = "$options.modal.id"
2020-03-13 15:44:24 +05:30
: title = "__('Delete pipeline')"
2022-08-13 15:12:31 +05:30
: action - primary = "$options.modal.actionPrimary"
: action - cancel = "$options.modal.actionCancel"
@ primary = "deletePipeline()"
2020-03-13 15:44:24 +05:30
>
< p >
{ { deleteModalConfirmationText } }
< / p >
< / gl-modal >
2017-09-10 17:25:29 +05:30
< / div >
< / template >