Commit 1ac15de9 authored by Filipa Lacerda's avatar Filipa Lacerda Committed by Phil Hughes

Resolve "Jobs dropdown in mini graph should close when we receive an error"

parent d71d09e8
......@@ -28,7 +28,9 @@ export default class MiniPipelineGraph {
* All dropdown events are fired at the .dropdown-menu's parent element.
*/
bindEvents() {
$(document).off('shown.bs.dropdown', this.container).on('shown.bs.dropdown', this.container, this.getBuildsList);
$(document)
.off('shown.bs.dropdown', this.container)
.on('shown.bs.dropdown', this.container, this.getBuildsList);
}
/**
......@@ -91,6 +93,9 @@ export default class MiniPipelineGraph {
},
error: () => {
this.toggleLoading(button);
if ($(button).parent().hasClass('open')) {
$(button).dropdown('toggle');
}
new Flash('An error occurred while fetching the builds.', 'alert');
},
});
......
......@@ -2,13 +2,6 @@
import StatusIconEntityMap from '../../ci_status_icons';
export default {
data() {
return {
builds: '',
spinner: '<span class="fa fa-spinner fa-spin"></span>',
};
},
props: {
stage: {
type: Object,
......@@ -16,6 +9,13 @@ export default {
},
},
data() {
return {
builds: '',
spinner: '<span class="fa fa-spinner fa-spin"></span>',
};
},
updated() {
if (this.builds) {
this.stopDropdownClickPropagation();
......@@ -31,7 +31,13 @@ export default {
return this.$http.get(this.stage.dropdown_path)
.then((response) => {
this.builds = JSON.parse(response.body).html;
}, () => {
})
.catch(() => {
// If dropdown is opened we'll close it.
if (this.$el.classList.contains('open')) {
$(this.$refs.dropdown).dropdown('toggle');
}
const flash = new Flash('Something went wrong on our end.');
return flash;
});
......@@ -46,7 +52,8 @@ export default {
* target the click event of this component.
*/
stopDropdownClickPropagation() {
$(this.$el.querySelectorAll('.js-builds-dropdown-list a.mini-pipeline-graph-dropdown-item')).on('click', (e) => {
$(this.$el.querySelectorAll('.js-builds-dropdown-list a.mini-pipeline-graph-dropdown-item'))
.on('click', (e) => {
e.stopPropagation();
});
},
......@@ -81,12 +88,22 @@ export default {
data-placement="top"
data-toggle="dropdown"
type="button"
:aria-label="stage.title">
<span v-html="svgHTML" aria-hidden="true"></span>
<i class="fa fa-caret-down" aria-hidden="true"></i>
:aria-label="stage.title"
ref="dropdown">
<span
v-html="svgHTML"
aria-hidden="true">
</span>
<i
class="fa fa-caret-down"
aria-hidden="true" />
</button>
<ul class="dropdown-menu mini-pipeline-graph-dropdown-menu js-builds-dropdown-container">
<div class="arrow-up" aria-hidden="true"></div>
<ul
ref="dropdown-content"
class="dropdown-menu mini-pipeline-graph-dropdown-menu js-builds-dropdown-container">
<div
class="arrow-up"
aria-hidden="true"></div>
<div
:class="dropdownClass"
class="js-builds-dropdown-list scrollable-menu"
......
......@@ -195,7 +195,6 @@
border: 1px solid $dropdown-border-color;
border-radius: $border-radius-base;
box-shadow: 0 2px 4px $dropdown-shadow-color;
overflow: hidden;
@include set-invisible;
@media (max-width: $screen-sm-min) {
......
......@@ -3,8 +3,7 @@
import MiniPipelineGraph from '~/mini_pipeline_graph_dropdown';
import '~/flash';
(() => {
describe('Mini Pipeline Graph Dropdown', () => {
describe('Mini Pipeline Graph Dropdown', () => {
preloadFixtures('static/mini_dropdown_graph.html.raw');
beforeEach(() => {
......@@ -29,7 +28,10 @@ import '~/flash';
describe('When dropdown is clicked', () => {
it('should call getBuildsList', () => {
const getBuildsListSpy = spyOn(MiniPipelineGraph.prototype, 'getBuildsList').and.callFake(function () {});
const getBuildsListSpy = spyOn(
MiniPipelineGraph.prototype,
'getBuildsList',
).and.callFake(function () {});
new MiniPipelineGraph({ container: '.js-builds-dropdown-tests' }).bindEvents();
......@@ -68,5 +70,17 @@ import '~/flash';
expect($('.js-builds-dropdown-list').is(':visible')).toEqual(true);
});
});
it('should close the dropdown when request returns an error', (done) => {
spyOn($, 'ajax').and.callFake(options => options.error());
new MiniPipelineGraph({ container: '.js-builds-dropdown-tests' }).bindEvents();
document.querySelector('.js-builds-dropdown-button').click();
setTimeout(() => {
expect($('.js-builds-dropdown-tests .dropdown').hasClass('open')).toEqual(false);
done();
}, 0);
});
})();
});
......@@ -63,4 +63,19 @@ describe('Pipelines Stage', () => {
expect(minifiedComponent).toContain(expectedSVG);
});
});
describe('when request fails', () => {
it('closes dropdown', () => {
spyOn($, 'ajax').and.callFake(options => options.error());
const StageComponent = Vue.extend(Stage);
const component = new StageComponent({
propsData: { stage: { status: { icon: 'foo' } } },
}).$mount();
expect(
component.$el.classList.contains('open'),
).toEqual(false);
});
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment