summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShah El-Rahman <selrahman@gitlab.com>2018-02-06 21:05:54 -0600
committerShah El-Rahman <selrahman@gitlab.com>2018-02-07 19:28:18 -0600
commit97f08c651e0c95e33dee4a529ff80472e7d3bbe4 (patch)
treeddd00533a9879daca6a9ed7e449a47e99fb8cfef
parentd2a2f22fe6b2e93630b32bc699d091720b01b6d3 (diff)
downloadgitlab-ce-41297-new-design-for-cancel-stop-pipeline-confirmation.tar.gz
Add modal for stopping and retrying pipelines41297-new-design-for-cancel-stop-pipeline-confirmation
Fix tests Address code review feedback Fix tests
-rw-r--r--app/assets/javascripts/groups/components/app.vue6
-rw-r--r--app/assets/javascripts/pipelines/components/async_button.vue16
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_table.vue6
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_table_row.vue7
-rw-r--r--app/assets/javascripts/pipelines/components/retry_confirmation_modal.vue65
-rw-r--r--app/assets/javascripts/pipelines/components/stop_confirmation_modal.vue65
-rw-r--r--spec/features/projects/pipelines/pipelines_spec.rb7
-rw-r--r--spec/javascripts/groups/components/app_spec.js12
-rw-r--r--spec/javascripts/pipelines/async_button_spec.js8
9 files changed, 167 insertions, 25 deletions
diff --git a/app/assets/javascripts/groups/components/app.vue b/app/assets/javascripts/groups/components/app.vue
index e035ba462db..b8f0566f48c 100644
--- a/app/assets/javascripts/groups/components/app.vue
+++ b/app/assets/javascripts/groups/components/app.vue
@@ -152,14 +152,14 @@ export default {
showLeaveGroupModal(group, parentGroup) {
this.targetGroup = group;
this.targetParentGroup = parentGroup;
- this.showModal = true;
+ this.updateModal = true;
this.groupLeaveConfirmationMessage = s__(`GroupsTree|Are you sure you want to leave the "${group.fullName}" group?`);
},
hideLeaveGroupModal() {
- this.showModal = false;
+ this.updateModal = false;
},
leaveGroup() {
- this.showModal = false;
+ this.updateModal = false;
this.targetGroup.isBeingRemoved = true;
this.service.leaveGroup(this.targetGroup.leavePath)
.then(res => res.json())
diff --git a/app/assets/javascripts/pipelines/components/async_button.vue b/app/assets/javascripts/pipelines/components/async_button.vue
index 77553ca67cc..a5f22c4ec80 100644
--- a/app/assets/javascripts/pipelines/components/async_button.vue
+++ b/app/assets/javascripts/pipelines/components/async_button.vue
@@ -31,10 +31,9 @@
type: String,
required: true,
},
- confirmActionMessage: {
- type: String,
- required: false,
- default: '',
+ id: {
+ type: Number,
+ required: true,
},
},
data() {
@@ -49,11 +48,10 @@
},
methods: {
onClick() {
- if (this.confirmActionMessage !== '' && confirm(this.confirmActionMessage)) {
- this.makeRequest();
- } else if (this.confirmActionMessage === '') {
- this.makeRequest();
- }
+ eventHub.$emit('actionConfirmationModal', {
+ id: this.id,
+ callback: this.makeRequest,
+ });
},
makeRequest() {
this.isLoading = true;
diff --git a/app/assets/javascripts/pipelines/components/pipelines_table.vue b/app/assets/javascripts/pipelines/components/pipelines_table.vue
index 6681b89e629..62fe479fdf4 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_table.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_table.vue
@@ -1,5 +1,7 @@
<script>
import pipelinesTableRowComponent from './pipelines_table_row.vue';
+ import stopConfirmationModal from './stop_confirmation_modal.vue';
+ import retryConfirmationModal from './retry_confirmation_modal.vue';
/**
* Pipelines Table Component.
@@ -9,6 +11,8 @@
export default {
components: {
pipelinesTableRowComponent,
+ stopConfirmationModal,
+ retryConfirmationModal,
},
props: {
pipelines: {
@@ -70,5 +74,7 @@
:auto-devops-help-path="autoDevopsHelpPath"
:view-type="viewType"
/>
+ <stop-confirmation-modal />
+ <retry-confirmation-modal />
</div>
</template>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_table_row.vue b/app/assets/javascripts/pipelines/components/pipelines_table_row.vue
index d0e4cf7ff40..0e3a10ed7f4 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_table_row.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_table_row.vue
@@ -305,6 +305,9 @@
css-class="js-pipelines-retry-button btn-default btn-retry"
title="Retry"
icon="repeat"
+ :id="pipeline.id"
+ data-toggle="modal"
+ data-target="#retry-confirmation-modal"
/>
<async-button-component
@@ -313,7 +316,9 @@
css-class="js-pipelines-cancel-button btn-remove"
title="Cancel"
icon="close"
- confirm-action-message="Are you sure you want to cancel this pipeline?"
+ :id="pipeline.id"
+ data-toggle="modal"
+ data-target="#stop-confirmation-modal"
/>
</div>
</div>
diff --git a/app/assets/javascripts/pipelines/components/retry_confirmation_modal.vue b/app/assets/javascripts/pipelines/components/retry_confirmation_modal.vue
new file mode 100644
index 00000000000..e2ac08d67bc
--- /dev/null
+++ b/app/assets/javascripts/pipelines/components/retry_confirmation_modal.vue
@@ -0,0 +1,65 @@
+<script>
+ import modal from '~/vue_shared/components/modal.vue';
+ import { s__, sprintf } from '~/locale';
+ import eventHub from '../event_hub';
+
+ export default {
+ components: {
+ modal,
+ },
+ data() {
+ return {
+ id: '',
+ callback: () => {},
+ };
+ },
+ computed: {
+ title() {
+ return sprintf(s__('Pipeline|Retry pipeline #%{id}?'), {
+ id: `'${this.id}'`,
+ }, false);
+ },
+ text() {
+ return sprintf(s__('Pipeline|You’re about to retry pipeline %{id}.'), {
+ id: `<strong>#${this.id}</strong>`,
+ }, false);
+ },
+ primaryButtonLabel() {
+ return s__('Pipeline|Retry pipeline');
+ },
+ },
+ created() {
+ eventHub.$on('actionConfirmationModal', this.updateModal);
+ },
+ beforeDestroy() {
+ eventHub.$off('actionConfirmationModal', this.updateModal);
+ },
+ methods: {
+ updateModal(action) {
+ this.id = action.id;
+ this.callback = action.callback;
+ },
+ onSubmit() {
+ this.callback();
+ },
+ },
+ };
+</script>
+
+<template>
+ <modal
+ id="retry-confirmation-modal"
+ :title="title"
+ :text="text"
+ kind="danger"
+ :primary-button-label="primaryButtonLabel"
+ @submit="onSubmit"
+ >
+ <template
+ slot="body"
+ slot-scope="props"
+ >
+ <p v-html="props.text"></p>
+ </template>
+ </modal>
+</template>
diff --git a/app/assets/javascripts/pipelines/components/stop_confirmation_modal.vue b/app/assets/javascripts/pipelines/components/stop_confirmation_modal.vue
new file mode 100644
index 00000000000..d737d567787
--- /dev/null
+++ b/app/assets/javascripts/pipelines/components/stop_confirmation_modal.vue
@@ -0,0 +1,65 @@
+<script>
+ import modal from '~/vue_shared/components/modal.vue';
+ import { s__, sprintf } from '~/locale';
+ import eventHub from '../event_hub';
+
+ export default {
+ components: {
+ modal,
+ },
+ data() {
+ return {
+ id: '',
+ callback: () => {},
+ };
+ },
+ computed: {
+ title() {
+ return sprintf(s__('Pipeline|Stop pipeline #%{id}?'), {
+ id: `'${this.id}'`,
+ }, false);
+ },
+ text() {
+ return sprintf(s__('Pipeline|You’re about to stop pipeline %{id}.'), {
+ id: `<strong>#${this.id}</strong>`,
+ }, false);
+ },
+ primaryButtonLabel() {
+ return s__('Pipeline|Stop pipeline');
+ },
+ },
+ created() {
+ eventHub.$on('actionConfirmationModal', this.updateModal);
+ },
+ beforeDestroy() {
+ eventHub.$off('actionConfirmationModal', this.updateModal);
+ },
+ methods: {
+ updateModal(action) {
+ this.id = action.id;
+ this.callback = action.callback;
+ },
+ onSubmit() {
+ this.callback();
+ },
+ },
+ };
+</script>
+
+<template>
+ <modal
+ id="stop-confirmation-modal"
+ :title="title"
+ :text="text"
+ kind="danger"
+ :primary-button-label="primaryButtonLabel"
+ @submit="onSubmit"
+ >
+ <template
+ slot="body"
+ slot-scope="props"
+ >
+ <p v-html="props.text"></p>
+ </template>
+ </modal>
+</template>
diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb
index 592c99fc64a..37a06b65481 100644
--- a/spec/features/projects/pipelines/pipelines_spec.rb
+++ b/spec/features/projects/pipelines/pipelines_spec.rb
@@ -109,7 +109,8 @@ describe 'Pipelines', :js do
context 'when canceling' do
before do
- accept_confirm { find('.js-pipelines-cancel-button').click }
+ find('.js-pipelines-cancel-button').click
+ find('.js-primary-button').click
wait_for_requests
end
@@ -140,6 +141,7 @@ 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
@@ -238,7 +240,8 @@ describe 'Pipelines', :js do
context 'when canceling' do
before do
- accept_alert { find('.js-pipelines-cancel-button').click }
+ find('.js-pipelines-cancel-button').click
+ find('.js-primary-button').click
end
it 'indicates that pipeline was canceled' do
diff --git a/spec/javascripts/groups/components/app_spec.js b/spec/javascripts/groups/components/app_spec.js
index 8338efe915b..3adc29262f3 100644
--- a/spec/javascripts/groups/components/app_spec.js
+++ b/spec/javascripts/groups/components/app_spec.js
@@ -268,10 +268,10 @@ describe('AppComponent', () => {
it('updates props which show modal confirmation dialog', () => {
const group = Object.assign({}, mockParentGroupItem);
- expect(vm.showModal).toBeFalsy();
+ expect(vm.updateModal).toBeFalsy();
expect(vm.groupLeaveConfirmationMessage).toBe('');
vm.showLeaveGroupModal(group, mockParentGroupItem);
- expect(vm.showModal).toBeTruthy();
+ expect(vm.updateModal).toBeTruthy();
expect(vm.groupLeaveConfirmationMessage).toBe(`Are you sure you want to leave the "${group.fullName}" group?`);
});
});
@@ -280,9 +280,9 @@ describe('AppComponent', () => {
it('hides modal confirmation which is shown before leaving the group', () => {
const group = Object.assign({}, mockParentGroupItem);
vm.showLeaveGroupModal(group, mockParentGroupItem);
- expect(vm.showModal).toBeTruthy();
+ expect(vm.updateModal).toBeTruthy();
vm.hideLeaveGroupModal();
- expect(vm.showModal).toBeFalsy();
+ expect(vm.updateModal).toBeFalsy();
});
});
@@ -307,7 +307,7 @@ describe('AppComponent', () => {
spyOn($, 'scrollTo');
vm.leaveGroup();
- expect(vm.showModal).toBeFalsy();
+ expect(vm.updateModal).toBeFalsy();
expect(vm.targetGroup.isBeingRemoved).toBeTruthy();
expect(vm.service.leaveGroup).toHaveBeenCalledWith(vm.targetGroup.leavePath);
setTimeout(() => {
@@ -475,7 +475,7 @@ describe('AppComponent', () => {
it('renders modal confirmation dialog', () => {
vm.groupLeaveConfirmationMessage = 'Are you sure you want to leave the "foo" group?';
- vm.showModal = true;
+ vm.updateModal = true;
const modalDialogEl = vm.$el.querySelector('.modal');
expect(modalDialogEl).not.toBe(null);
expect(modalDialogEl.querySelector('.modal-title').innerText.trim()).toBe('Are you sure?');
diff --git a/spec/javascripts/pipelines/async_button_spec.js b/spec/javascripts/pipelines/async_button_spec.js
index d010d897642..8ce33d410a7 100644
--- a/spec/javascripts/pipelines/async_button_spec.js
+++ b/spec/javascripts/pipelines/async_button_spec.js
@@ -15,6 +15,7 @@ describe('Pipelines Async Button', () => {
title: 'Foo',
icon: 'repeat',
cssClass: 'bar',
+ id: 123,
},
}).$mount();
});
@@ -38,9 +39,8 @@ describe('Pipelines Async Button', () => {
describe('With confirm dialog', () => {
it('should call the service when confimation is positive', () => {
- spyOn(window, 'confirm').and.returnValue(true);
- eventHub.$on('postAction', (endpoint) => {
- expect(endpoint).toEqual('/foo');
+ eventHub.$on('actionConfirmationModal', (data) => {
+ expect(data.id).toEqual(123);
});
component = new AsyncButtonComponent({
@@ -49,7 +49,7 @@ describe('Pipelines Async Button', () => {
title: 'Foo',
icon: 'fa fa-foo',
cssClass: 'bar',
- confirmActionMessage: 'bar',
+ id: 123,
},
}).$mount();