Commit 48b93f7a authored by Filipa Lacerda's avatar Filipa Lacerda

Hides loading spinner after request

In the pipeline's actions, moves the request
to the component to allow to manage the inner
state properly
parent 32d89f07
<script> <script>
import { GlButton, GlTooltipDirective, GlLoadingIcon } from '@gitlab/ui'; import { GlButton, GlTooltipDirective, GlLoadingIcon } from '@gitlab/ui';
import { s__, sprintf } from '~/locale'; import axios from '~/lib/utils/axios_utils';
import flash from '~/flash';
import { s__, __, sprintf } from '~/locale';
import GlCountdown from '~/vue_shared/components/gl_countdown.vue'; import GlCountdown from '~/vue_shared/components/gl_countdown.vue';
import Icon from '~/vue_shared/components/icon.vue';
import eventHub from '../event_hub'; import eventHub from '../event_hub';
import Icon from '../../vue_shared/components/icon.vue';
export default { export default {
directives: { directives: {
...@@ -44,7 +46,24 @@ export default { ...@@ -44,7 +46,24 @@ export default {
this.isLoading = true; this.isLoading = true;
eventHub.$emit('postAction', action.path); /**
* Ideally, the component would not make an api call directly.
* However, in order to use the eventhub and know when to
* toggle back the `isLoading` property we'd need an ID
* to track the request with a wacther - since this component
* is rendered at least 20 times in the same page, moving the
* api call directly here is the most performant solution
*/
axios
.post(`${action.path}.json`)
.then(() => {
this.isLoading = false;
eventHub.$emit('updateTable');
})
.catch(() => {
this.isLoading = false;
flash(__('An error occurred while making the request.'));
});
}, },
isActionDisabled(action) { isActionDisabled(action) {
......
...@@ -60,12 +60,14 @@ export default { ...@@ -60,12 +60,14 @@ export default {
eventHub.$on('postAction', this.postAction); eventHub.$on('postAction', this.postAction);
eventHub.$on('retryPipeline', this.postAction); eventHub.$on('retryPipeline', this.postAction);
eventHub.$on('clickedDropdown', this.updateTable); eventHub.$on('clickedDropdown', this.updateTable);
eventHub.$on('updateTable', this.updateTable);
eventHub.$on('refreshPipelinesTable', this.fetchPipelines); eventHub.$on('refreshPipelinesTable', this.fetchPipelines);
}, },
beforeDestroy() { beforeDestroy() {
eventHub.$off('postAction', this.postAction); eventHub.$off('postAction', this.postAction);
eventHub.$off('retryPipeline', this.postAction); eventHub.$off('retryPipeline', this.postAction);
eventHub.$off('clickedDropdown', this.updateTable); eventHub.$off('clickedDropdown', this.updateTable);
eventHub.$off('updateTable', this.updateTable);
eventHub.$off('refreshPipelinesTable', this.fetchPipelines); eventHub.$off('refreshPipelinesTable', this.fetchPipelines);
}, },
destroyed() { destroyed() {
......
---
title: Hides loading spinner in pipelines actions after request has been fullfiled
merge_request:
author:
type: fixed
import Vue from 'vue'; import Vue from 'vue';
import eventHub from '~/pipelines/event_hub'; import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import PipelinesActions from '~/pipelines/components/pipelines_actions.vue'; import PipelinesActions from '~/pipelines/components/pipelines_actions.vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper'; import mountComponent from 'spec/helpers/vue_mount_component_helper';
import { TEST_HOST } from 'spec/test_constants'; import { TEST_HOST } from 'spec/test_constants';
...@@ -7,9 +8,15 @@ import { TEST_HOST } from 'spec/test_constants'; ...@@ -7,9 +8,15 @@ import { TEST_HOST } from 'spec/test_constants';
describe('Pipelines Actions dropdown', () => { describe('Pipelines Actions dropdown', () => {
const Component = Vue.extend(PipelinesActions); const Component = Vue.extend(PipelinesActions);
let vm; let vm;
let mock;
afterEach(() => { afterEach(() => {
vm.$destroy(); vm.$destroy();
mock.restore();
});
beforeEach(() => {
mock = new MockAdapter(axios);
}); });
describe('manual actions', () => { describe('manual actions', () => {
...@@ -40,6 +47,22 @@ describe('Pipelines Actions dropdown', () => { ...@@ -40,6 +47,22 @@ describe('Pipelines Actions dropdown', () => {
expect(dropdownItem).toBeDisabled(); expect(dropdownItem).toBeDisabled();
}); });
describe('on click', () => {
it('makes a request and toggles the loading state', done => {
mock.onPost(actions.path).reply(200);
vm.$el.querySelector('.dropdown-menu li button').click();
expect(vm.isLoading).toEqual(true);
setTimeout(() => {
expect(vm.isLoading).toEqual(false);
done();
});
});
});
}); });
describe('scheduled jobs', () => { describe('scheduled jobs', () => {
...@@ -71,26 +94,27 @@ describe('Pipelines Actions dropdown', () => { ...@@ -71,26 +94,27 @@ describe('Pipelines Actions dropdown', () => {
.catch(done.fail); .catch(done.fail);
}); });
it('emits postAction event after confirming', () => { it('makes post request after confirming', done => {
const emitSpy = jasmine.createSpy('emit'); mock.onPost(scheduledJobAction.path).reply(200);
eventHub.$on('postAction', emitSpy);
spyOn(window, 'confirm').and.callFake(() => true); spyOn(window, 'confirm').and.callFake(() => true);
findDropdownItem(scheduledJobAction).click(); findDropdownItem(scheduledJobAction).click();
expect(window.confirm).toHaveBeenCalled(); expect(window.confirm).toHaveBeenCalled();
expect(emitSpy).toHaveBeenCalledWith(scheduledJobAction.path); setTimeout(() => {
expect(mock.history.post.length).toBe(1);
done();
});
}); });
it('does not emit postAction event if confirmation is cancelled', () => { it('does not make post request if confirmation is cancelled', () => {
const emitSpy = jasmine.createSpy('emit'); mock.onPost(scheduledJobAction.path).reply(200);
eventHub.$on('postAction', emitSpy);
spyOn(window, 'confirm').and.callFake(() => false); spyOn(window, 'confirm').and.callFake(() => false);
findDropdownItem(scheduledJobAction).click(); findDropdownItem(scheduledJobAction).click();
expect(window.confirm).toHaveBeenCalled(); expect(window.confirm).toHaveBeenCalled();
expect(emitSpy).not.toHaveBeenCalled(); expect(mock.history.post.length).toBe(0);
}); });
it('displays the remaining time in the dropdown', () => { it('displays the remaining time in the dropdown', () => {
......
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