summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilipa Lacerda <filipa@gitlab.com>2019-08-05 14:51:08 +0100
committerFilipa Lacerda <filipa@gitlab.com>2019-08-06 11:30:10 +0100
commit48b93f7aee2e00c8ab6263591f8c4ba90436bdf9 (patch)
tree423a09b67c34db2b31d4b28fc29ca352f9191143
parent32d89f07f5569c5ca6248dc50866a545cdfee58f (diff)
downloadgitlab-ce-65263-manual-action.tar.gz
Hides loading spinner after request65263-manual-action
In the pipeline's actions, moves the request to the component to allow to manage the inner state properly
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_actions.vue25
-rw-r--r--app/assets/javascripts/pipelines/mixins/pipelines.js2
-rw-r--r--changelogs/unreleased/65263-manual-action.yml5
-rw-r--r--spec/javascripts/pipelines/pipelines_actions_spec.js42
4 files changed, 62 insertions, 12 deletions
diff --git a/app/assets/javascripts/pipelines/components/pipelines_actions.vue b/app/assets/javascripts/pipelines/components/pipelines_actions.vue
index 244d332f38f..4b2d816c6a0 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_actions.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_actions.vue
@@ -1,9 +1,11 @@
<script>
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 Icon from '~/vue_shared/components/icon.vue';
import eventHub from '../event_hub';
-import Icon from '../../vue_shared/components/icon.vue';
export default {
directives: {
@@ -44,7 +46,24 @@ export default {
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) {
diff --git a/app/assets/javascripts/pipelines/mixins/pipelines.js b/app/assets/javascripts/pipelines/mixins/pipelines.js
index a6243366375..126a9a47a2b 100644
--- a/app/assets/javascripts/pipelines/mixins/pipelines.js
+++ b/app/assets/javascripts/pipelines/mixins/pipelines.js
@@ -60,12 +60,14 @@ export default {
eventHub.$on('postAction', this.postAction);
eventHub.$on('retryPipeline', this.postAction);
eventHub.$on('clickedDropdown', this.updateTable);
+ eventHub.$on('updateTable', this.updateTable);
eventHub.$on('refreshPipelinesTable', this.fetchPipelines);
},
beforeDestroy() {
eventHub.$off('postAction', this.postAction);
eventHub.$off('retryPipeline', this.postAction);
eventHub.$off('clickedDropdown', this.updateTable);
+ eventHub.$off('updateTable', this.updateTable);
eventHub.$off('refreshPipelinesTable', this.fetchPipelines);
},
destroyed() {
diff --git a/changelogs/unreleased/65263-manual-action.yml b/changelogs/unreleased/65263-manual-action.yml
new file mode 100644
index 00000000000..47b2a2ed329
--- /dev/null
+++ b/changelogs/unreleased/65263-manual-action.yml
@@ -0,0 +1,5 @@
+---
+title: Hides loading spinner in pipelines actions after request has been fullfiled
+merge_request:
+author:
+type: fixed
diff --git a/spec/javascripts/pipelines/pipelines_actions_spec.js b/spec/javascripts/pipelines/pipelines_actions_spec.js
index a7dcd532f4f..953a42b9d15 100644
--- a/spec/javascripts/pipelines/pipelines_actions_spec.js
+++ b/spec/javascripts/pipelines/pipelines_actions_spec.js
@@ -1,5 +1,6 @@
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 mountComponent from 'spec/helpers/vue_mount_component_helper';
import { TEST_HOST } from 'spec/test_constants';
@@ -7,9 +8,15 @@ import { TEST_HOST } from 'spec/test_constants';
describe('Pipelines Actions dropdown', () => {
const Component = Vue.extend(PipelinesActions);
let vm;
+ let mock;
afterEach(() => {
vm.$destroy();
+ mock.restore();
+ });
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
});
describe('manual actions', () => {
@@ -40,6 +47,22 @@ describe('Pipelines Actions dropdown', () => {
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', () => {
@@ -71,26 +94,27 @@ describe('Pipelines Actions dropdown', () => {
.catch(done.fail);
});
- it('emits postAction event after confirming', () => {
- const emitSpy = jasmine.createSpy('emit');
- eventHub.$on('postAction', emitSpy);
+ it('makes post request after confirming', done => {
+ mock.onPost(scheduledJobAction.path).reply(200);
spyOn(window, 'confirm').and.callFake(() => true);
findDropdownItem(scheduledJobAction).click();
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', () => {
- const emitSpy = jasmine.createSpy('emit');
- eventHub.$on('postAction', emitSpy);
+ it('does not make post request if confirmation is cancelled', () => {
+ mock.onPost(scheduledJobAction.path).reply(200);
spyOn(window, 'confirm').and.callFake(() => false);
findDropdownItem(scheduledJobAction).click();
expect(window.confirm).toHaveBeenCalled();
- expect(emitSpy).not.toHaveBeenCalled();
+ expect(mock.history.post.length).toBe(0);
});
it('displays the remaining time in the dropdown', () => {