Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Léo-Paul Géneau
gitlab-ce
Commits
feb9caab
Commit
feb9caab
authored
May 11, 2018
by
Filipa Lacerda
Committed by
Phil Hughes
May 11, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Resolve "Remove modal box confirmation when retrying a pipeline"
parent
27d0c429
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
124 additions
and
241 deletions
+124
-241
app/assets/javascripts/pipelines/components/async_button.vue
app/assets/javascripts/pipelines/components/async_button.vue
+0
-95
app/assets/javascripts/pipelines/components/pipelines_table.vue
...sets/javascripts/pipelines/components/pipelines_table.vue
+18
-35
app/assets/javascripts/pipelines/components/pipelines_table_row.vue
.../javascripts/pipelines/components/pipelines_table_row.vue
+60
-36
app/assets/javascripts/pipelines/mixins/pipelines.js
app/assets/javascripts/pipelines/mixins/pipelines.js
+2
-0
app/assets/javascripts/vue_shared/components/loading_button.vue
...sets/javascripts/vue_shared/components/loading_button.vue
+8
-6
changelogs/unreleased/45715-remove-modal-retry.yml
changelogs/unreleased/45715-remove-modal-retry.yml
+5
-0
spec/features/projects/pipelines/pipelines_spec.rb
spec/features/projects/pipelines/pipelines_spec.rb
+2
-3
spec/javascripts/pipelines/async_button_spec.js
spec/javascripts/pipelines/async_button_spec.js
+0
-62
spec/javascripts/pipelines/pipelines_table_row_spec.js
spec/javascripts/pipelines/pipelines_table_row_spec.js
+29
-4
No files found.
app/assets/javascripts/pipelines/components/async_button.vue
deleted
100644 → 0
View file @
27d0c429
<
script
>
/* eslint-disable no-alert */
import
eventHub
from
'
../event_hub
'
;
import
loadingIcon
from
'
../../vue_shared/components/loading_icon.vue
'
;
import
icon
from
'
../../vue_shared/components/icon.vue
'
;
import
tooltip
from
'
../../vue_shared/directives/tooltip
'
;
export
default
{
directives
:
{
tooltip
,
},
components
:
{
loadingIcon
,
icon
,
},
props
:
{
endpoint
:
{
type
:
String
,
required
:
true
,
},
title
:
{
type
:
String
,
required
:
true
,
},
icon
:
{
type
:
String
,
required
:
true
,
},
cssClass
:
{
type
:
String
,
required
:
true
,
},
pipelineId
:
{
type
:
Number
,
required
:
true
,
},
type
:
{
type
:
String
,
required
:
true
,
},
},
data
()
{
return
{
isLoading
:
false
,
};
},
computed
:
{
buttonClass
()
{
return
`btn
${
this
.
cssClass
}
`
;
},
},
created
()
{
// We're using eventHub to listen to the modal here instead of
// using props because it would would make the parent components
// much more complex to keep track of the loading state of each button
eventHub
.
$on
(
'
postAction
'
,
this
.
setLoading
);
},
beforeDestroy
()
{
eventHub
.
$off
(
'
postAction
'
,
this
.
setLoading
);
},
methods
:
{
onClick
()
{
eventHub
.
$emit
(
'
openConfirmationModal
'
,
{
pipelineId
:
this
.
pipelineId
,
endpoint
:
this
.
endpoint
,
type
:
this
.
type
,
});
},
setLoading
(
endpoint
)
{
if
(
endpoint
===
this
.
endpoint
)
{
this
.
isLoading
=
true
;
}
},
},
};
</
script
>
<
template
>
<button
v-tooltip
type=
"button"
@
click=
"onClick"
:class=
"buttonClass"
:title=
"title"
:aria-label=
"title"
data-container=
"body"
data-placement=
"top"
:disabled=
"isLoading"
>
<icon
:name=
"icon"
/>
<loading-icon
v-if=
"isLoading"
/>
</button>
</
template
>
app/assets/javascripts/pipelines/components/pipelines_table.vue
View file @
feb9caab
<
script
>
import
DeprecatedModal
from
'
~/vue_shared/components/deprecated
_modal.vue
'
;
import
Modal
from
'
~/vue_shared/components/gl
_modal.vue
'
;
import
{
s__
,
sprintf
}
from
'
~/locale
'
;
import
p
ipelinesTableRowComponent
from
'
./pipelines_table_row.vue
'
;
import
P
ipelinesTableRowComponent
from
'
./pipelines_table_row.vue
'
;
import
eventHub
from
'
../event_hub
'
;
/**
...
...
@@ -11,8 +11,8 @@
*/
export
default
{
components
:
{
p
ipelinesTableRowComponent
,
Deprecated
Modal
,
P
ipelinesTableRowComponent
,
Modal
,
},
props
:
{
pipelines
:
{
...
...
@@ -37,31 +37,19 @@
return
{
pipelineId
:
''
,
endpoint
:
''
,
type
:
''
,
};
},
computed
:
{
modalTitle
()
{
return
this
.
type
===
'
stop
'
?
sprintf
(
s__
(
'
Pipeline|Stop pipeline #%{pipelineId}?
'
),
{
pipelineId
:
`'
${
this
.
pipelineId
}
'`
,
},
false
)
:
sprintf
(
s__
(
'
Pipeline|Retry pipeline #%{pipelineId}?
'
),
{
pipelineId
:
`'
${
this
.
pipelineId
}
'`
,
return
sprintf
(
s__
(
'
Pipeline|Stop pipeline #%{pipelineId}?
'
),
{
pipelineId
:
`
${
this
.
pipelineId
}
`
,
},
false
);
},
modalText
()
{
return
this
.
type
===
'
stop
'
?
sprintf
(
s__
(
'
Pipeline|You’re about to stop pipeline %{pipelineId}.
'
),
{
pipelineId
:
`<strong>#
${
this
.
pipelineId
}
</strong>`
,
},
false
)
:
sprintf
(
s__
(
'
Pipeline|You’re about to retry pipeline %{pipelineId}.
'
),
{
return
sprintf
(
s__
(
'
Pipeline|You’re about to stop pipeline %{pipelineId}.
'
),
{
pipelineId
:
`<strong>#
${
this
.
pipelineId
}
</strong>`
,
},
false
);
},
primaryButtonLabel
()
{
return
this
.
type
===
'
stop
'
?
s__
(
'
Pipeline|Stop pipeline
'
)
:
s__
(
'
Pipeline|Retry pipeline
'
);
},
},
created
()
{
eventHub
.
$on
(
'
openConfirmationModal
'
,
this
.
setModalData
);
...
...
@@ -73,7 +61,6 @@
setModalData
(
data
)
{
this
.
pipelineId
=
data
.
pipelineId
;
this
.
endpoint
=
data
.
endpoint
;
this
.
type
=
data
.
type
;
},
onSubmit
()
{
eventHub
.
$emit
(
'
postAction
'
,
this
.
endpoint
);
...
...
@@ -120,20 +107,16 @@
:auto-devops-help-path=
"autoDevopsHelpPath"
:view-type=
"viewType"
/>
<deprecated-modal
<modal
id=
"confirmation-modal"
:title=
"modalTitle"
:text=
"modalText"
kind=
"danger"
:primary-button-label=
"primaryButtonLabel"
:header-title-text=
"modalTitle"
footer-primary-button-variant=
"danger"
:footer-primary-button-text=
"s__('Pipeline|Stop pipeline')"
@
submit=
"onSubmit"
>
<template
slot=
"body"
slot-scope=
"props"
>
<p
v-html=
"props.text"
></p>
</
template
>
</deprecated-modal>
<span
v-html=
"modalText"
></span>
</modal>
</div>
</
template
>
app/assets/javascripts/pipelines/components/pipelines_table_row.vue
View file @
feb9caab
<
script
>
/* eslint-disable no-param-reassign */
import
asyncButtonComponent
from
'
./async_button.vue
'
;
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
pipelinesTimeago
from
'
./time_ago.vue
'
;
import
commitComponent
from
'
../../vue_shared/components/commit.vue
'
;
import
eventHub
from
'
../event_hub
'
;
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
PipelinesTimeago
from
'
./time_ago.vue
'
;
import
CommitComponent
from
'
../../vue_shared/components/commit.vue
'
;
import
LoadingButton
from
'
../../vue_shared/components/loading_button.vue
'
;
import
Icon
from
'
../../vue_shared/components/icon.vue
'
;
/**
* Pipeline table row.
...
...
@@ -16,14 +17,15 @@
*/
export
default
{
components
:
{
asyncButtonComponent
,
pipelinesActionsComponent
,
pipelinesArtifactsComponent
,
commitComponent
,
pipelineStage
,
pipelineUrl
,
ciBadge
,
pipelinesTimeago
,
PipelinesActionsComponent
,
PipelinesArtifactsComponent
,
CommitComponent
,
PipelineStage
,
PipelineUrl
,
CiBadge
,
PipelinesTimeago
,
LoadingButton
,
Icon
,
},
props
:
{
pipeline
:
{
...
...
@@ -44,6 +46,12 @@
required
:
true
,
},
},
data
()
{
return
{
isRetrying
:
false
,
isCancelling
:
false
,
};
},
computed
:
{
/**
* If provided, returns the commit tag.
...
...
@@ -119,8 +127,10 @@
if
(
this
.
pipeline
.
ref
)
{
return
Object
.
keys
(
this
.
pipeline
.
ref
).
reduce
((
accumulator
,
prop
)
=>
{
if
(
prop
===
'
path
'
)
{
// eslint-disable-next-line no-param-reassign
accumulator
.
ref_url
=
this
.
pipeline
.
ref
[
prop
];
}
else
{
// eslint-disable-next-line no-param-reassign
accumulator
[
prop
]
=
this
.
pipeline
.
ref
[
prop
];
}
return
accumulator
;
...
...
@@ -216,6 +226,21 @@
return
this
.
viewType
===
'
child
'
;
},
},
methods
:
{
handleCancelClick
()
{
this
.
isCancelling
=
true
;
eventHub
.
$emit
(
'
openConfirmationModal
'
,
{
pipelineId
:
this
.
pipeline
.
id
,
endpoint
:
this
.
pipeline
.
cancel_path
,
});
},
handleRetryClick
()
{
this
.
isRetrying
=
true
;
eventHub
.
$emit
(
'
retryPipeline
'
,
this
.
pipeline
.
retry_path
);
},
},
};
</
script
>
<
template
>
...
...
@@ -287,7 +312,8 @@
<div
v-if=
"displayPipelineActions"
class=
"table-section section-20 table-button-footer pipeline-actions"
>
class=
"table-section section-20 table-button-footer pipeline-actions"
>
<div
class=
"btn-group table-action-buttons"
>
<pipelines-actions-component
v-if=
"pipeline.details.manual_actions.length"
...
...
@@ -300,29 +326,27 @@
:artifacts=
"pipeline.details.artifacts"
/>
<
async-button-component
<
loading-button
v-if=
"pipeline.flags.retryable"
:endpoint=
"pipeline.retry_path"
css-class=
"js-pipelines-retry-button btn-default btn-retry"
title=
"Retry"
icon=
"repeat"
:pipeline-id=
"pipeline.id"
data-toggle=
"modal"
data-target=
"#confirmation-modal"
type=
"retry"
/>
@
click=
"handleRetryClick"
container-class=
"js-pipelines-retry-button btn btn-default btn-retry"
:loading=
"isRetrying"
:disabled=
"isRetrying"
>
<icon
name=
"repeat"
/>
</loading-button>
<
async-button-component
<
loading-button
v-if=
"pipeline.flags.cancelable"
:endpoint=
"pipeline.cancel_path"
css-class=
"js-pipelines-cancel-button btn-remove"
title=
"Stop"
icon=
"close"
:pipeline-id=
"pipeline.id"
@
click=
"handleCancelClick"
data-toggle=
"modal"
data-target=
"#confirmation-modal"
type=
"stop"
/>
container-class=
"js-pipelines-cancel-button btn btn-remove"
:loading=
"isCancelling"
:disabled=
"isCancelling"
>
<icon
name=
"close"
/>
</loading-button>
</div>
</div>
</div>
...
...
app/assets/javascripts/pipelines/mixins/pipelines.js
View file @
feb9caab
...
...
@@ -53,10 +53,12 @@ export default {
});
eventHub
.
$on
(
'
postAction
'
,
this
.
postAction
);
eventHub
.
$on
(
'
retryPipeline
'
,
this
.
postAction
);
eventHub
.
$on
(
'
clickedDropdown
'
,
this
.
updateTable
);
},
beforeDestroy
()
{
eventHub
.
$off
(
'
postAction
'
,
this
.
postAction
);
eventHub
.
$off
(
'
retryPipeline
'
,
this
.
postAction
);
eventHub
.
$off
(
'
clickedDropdown
'
,
this
.
updateTable
);
},
destroyed
()
{
...
...
app/assets/javascripts/vue_shared/components/loading_button.vue
View file @
feb9caab
...
...
@@ -70,12 +70,14 @@
/>
</transition>
<transition
name=
"fade"
>
<slot>
<span
v-if=
"label"
class=
"js-loading-button-label"
>
{{
label
}}
</span>
</slot>
</transition>
</button>
</
template
>
changelogs/unreleased/45715-remove-modal-retry.yml
0 → 100644
View file @
feb9caab
---
title
:
Remove modalbox confirmation when retrying a pipeline
merge_request
:
18879
author
:
type
:
changed
spec/features/projects/pipelines/pipelines_spec.rb
View file @
feb9caab
...
...
@@ -125,7 +125,7 @@ describe 'Pipelines', :js do
context
'when canceling'
do
before
do
find
(
'.js-pipelines-cancel-button'
).
click
find
(
'.js-
primary-butt
on'
).
click
find
(
'.js-
modal-primary-acti
on'
).
click
wait_for_requests
end
...
...
@@ -156,7 +156,6 @@ describe 'Pipelines', :js do
context
'when retrying'
do
before
do
find
(
'.js-pipelines-retry-button'
).
click
find
(
'.js-primary-button'
).
click
wait_for_requests
end
...
...
@@ -256,7 +255,7 @@ describe 'Pipelines', :js do
context
'when canceling'
do
before
do
find
(
'.js-pipelines-cancel-button'
).
click
find
(
'.js-
primary-butt
on'
).
click
find
(
'.js-
modal-primary-acti
on'
).
click
end
it
'indicates that pipeline was canceled'
do
...
...
spec/javascripts/pipelines/async_button_spec.js
deleted
100644 → 0
View file @
27d0c429
import
Vue
from
'
vue
'
;
import
asyncButtonComp
from
'
~/pipelines/components/async_button.vue
'
;
import
eventHub
from
'
~/pipelines/event_hub
'
;
describe
(
'
Pipelines Async Button
'
,
()
=>
{
let
component
;
let
AsyncButtonComponent
;
beforeEach
(()
=>
{
AsyncButtonComponent
=
Vue
.
extend
(
asyncButtonComp
);
component
=
new
AsyncButtonComponent
({
propsData
:
{
endpoint
:
'
/foo
'
,
title
:
'
Foo
'
,
icon
:
'
repeat
'
,
cssClass
:
'
bar
'
,
pipelineId
:
123
,
type
:
'
explode
'
,
},
}).
$mount
();
});
it
(
'
should render a button
'
,
()
=>
{
expect
(
component
.
$el
.
tagName
).
toEqual
(
'
BUTTON
'
);
});
it
(
'
should render svg icon
'
,
()
=>
{
expect
(
component
.
$el
.
querySelector
(
'
svg
'
)).
not
.
toBeNull
();
});
it
(
'
should render the provided title
'
,
()
=>
{
expect
(
component
.
$el
.
getAttribute
(
'
data-original-title
'
)).
toContain
(
'
Foo
'
);
expect
(
component
.
$el
.
getAttribute
(
'
aria-label
'
)).
toContain
(
'
Foo
'
);
});
it
(
'
should render the provided cssClass
'
,
()
=>
{
expect
(
component
.
$el
.
getAttribute
(
'
class
'
)).
toContain
(
'
bar
'
);
});
describe
(
'
With confirm dialog
'
,
()
=>
{
it
(
'
should call the service when confimation is positive
'
,
()
=>
{
eventHub
.
$on
(
'
openConfirmationModal
'
,
(
data
)
=>
{
expect
(
data
.
pipelineId
).
toEqual
(
123
);
expect
(
data
.
type
).
toEqual
(
'
explode
'
);
});
component
=
new
AsyncButtonComponent
({
propsData
:
{
endpoint
:
'
/foo
'
,
title
:
'
Foo
'
,
icon
:
'
fa fa-foo
'
,
cssClass
:
'
bar
'
,
pipelineId
:
123
,
type
:
'
explode
'
,
},
}).
$mount
();
component
.
$el
.
click
();
});
});
});
spec/javascripts/pipelines/pipelines_table_row_spec.js
View file @
feb9caab
import
Vue
from
'
vue
'
;
import
tableRowComp
from
'
~/pipelines/components/pipelines_table_row.vue
'
;
import
eventHub
from
'
~/pipelines/event_hub
'
;
describe
(
'
Pipelines Table Row
'
,
()
=>
{
const
jsonFixtureName
=
'
pipelines/pipelines.json
'
;
...
...
@@ -151,13 +152,37 @@ describe('Pipelines Table Row', () => {
describe
(
'
actions column
'
,
()
=>
{
beforeEach
(()
=>
{
component
=
buildComponent
(
pipeline
);
const
withActions
=
Object
.
assign
({},
pipeline
);
withActions
.
flags
.
cancelable
=
true
;
withActions
.
flags
.
retryable
=
true
;
withActions
.
cancel_path
=
'
/cancel
'
;
withActions
.
retry_path
=
'
/retry
'
;
component
=
buildComponent
(
withActions
);
});
it
(
'
should render the provided actions
'
,
()
=>
{
expect
(
component
.
$el
.
querySelectorAll
(
'
.table-section:nth-child(6) ul li
'
).
length
,
).
toEqual
(
pipeline
.
details
.
manual_actions
.
length
);
expect
(
component
.
$el
.
querySelector
(
'
.js-pipelines-retry-button
'
)).
not
.
toBeNull
();
expect
(
component
.
$el
.
querySelector
(
'
.js-pipelines-cancel-button
'
)).
not
.
toBeNull
();
});
it
(
'
emits `retryPipeline` event when retry button is clicked and toggles loading
'
,
()
=>
{
eventHub
.
$on
(
'
retryPipeline
'
,
(
endpoint
)
=>
{
expect
(
endpoint
).
toEqual
(
'
/retry
'
);
});
component
.
$el
.
querySelector
(
'
.js-pipelines-retry-button
'
).
click
();
expect
(
component
.
isRetrying
).
toEqual
(
true
);
});
it
(
'
emits `openConfirmationModal` event when cancel button is clicked and toggles loading
'
,
()
=>
{
eventHub
.
$on
(
'
openConfirmationModal
'
,
(
data
)
=>
{
expect
(
data
.
endpoint
).
toEqual
(
'
/cancel
'
);
expect
(
data
.
pipelineId
).
toEqual
(
pipeline
.
id
);
});
component
.
$el
.
querySelector
(
'
.js-pipelines-cancel-button
'
).
click
();
expect
(
component
.
isCancelling
).
toEqual
(
true
);
});
});
});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment