Commit fd92bd24 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '65263-manual-action' into 'master'

Hides loading spinner after request

Closes #65263

See merge request gitlab-org/gitlab-ce!31478
parents 914ebb2c 48b93f7a
<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