Commit c3d8bc35 authored by Filipa Lacerda's avatar Filipa Lacerda

Merge branch 'backport-delete-epic' into 'master'

Backport delete epic changes

Closes #40162

See merge request gitlab-org/gitlab-ce!15414
parents 4d555032 c6c493a7
...@@ -29,6 +29,11 @@ export default { ...@@ -29,6 +29,11 @@ export default {
required: false, required: false,
default: false, default: false,
}, },
showDeleteButton: {
type: Boolean,
required: false,
default: true,
},
issuableRef: { issuableRef: {
type: String, type: String,
required: true, required: true,
...@@ -92,6 +97,11 @@ export default { ...@@ -92,6 +97,11 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
issuableType: {
type: String,
required: false,
default: 'issue',
},
}, },
data() { data() {
const store = new Store({ const store = new Store({
...@@ -157,21 +167,21 @@ export default { ...@@ -157,21 +167,21 @@ export default {
}) })
.catch(() => { .catch(() => {
eventHub.$emit('close.form'); eventHub.$emit('close.form');
window.Flash('Error updating issue'); window.Flash(`Error updating ${this.issuableType}`);
}); });
}, },
deleteIssuable() { deleteIssuable() {
this.service.deleteIssuable() this.service.deleteIssuable()
.then(res => res.json()) .then(res => res.json())
.then((data) => { .then((data) => {
// Stop the poll so we don't get 404's with the issue not existing // Stop the poll so we don't get 404's with the issuable not existing
this.poll.stop(); this.poll.stop();
gl.utils.visitUrl(data.web_url); gl.utils.visitUrl(data.web_url);
}) })
.catch(() => { .catch(() => {
eventHub.$emit('close.form'); eventHub.$emit('close.form');
window.Flash('Error deleting issue'); window.Flash(`Error deleting ${this.issuableType}`);
}); });
}, },
}, },
...@@ -223,6 +233,7 @@ export default { ...@@ -223,6 +233,7 @@ export default {
:markdown-preview-path="markdownPreviewPath" :markdown-preview-path="markdownPreviewPath"
:project-path="projectPath" :project-path="projectPath"
:project-namespace="projectNamespace" :project-namespace="projectNamespace"
:show-delete-button="showDeleteButton"
/> />
<div v-else> <div v-else>
<title-component <title-component
......
...@@ -13,6 +13,11 @@ ...@@ -13,6 +13,11 @@
type: Object, type: Object,
required: true, required: true,
}, },
showDeleteButton: {
type: Boolean,
required: false,
default: true,
},
}, },
data() { data() {
return { return {
...@@ -23,6 +28,9 @@ ...@@ -23,6 +28,9 @@
isSubmitEnabled() { isSubmitEnabled() {
return this.formState.title.trim() !== ''; return this.formState.title.trim() !== '';
}, },
shouldShowDeleteButton() {
return this.canDestroy && this.showDeleteButton;
},
}, },
methods: { methods: {
closeForm() { closeForm() {
...@@ -62,7 +70,7 @@ ...@@ -62,7 +70,7 @@
Cancel Cancel
</button> </button>
<button <button
v-if="canDestroy" v-if="shouldShowDeleteButton"
class="btn btn-danger pull-right append-right-default" class="btn btn-danger pull-right append-right-default"
:class="{ disabled: deleteLoading }" :class="{ disabled: deleteLoading }"
type="button" type="button"
......
...@@ -36,6 +36,11 @@ ...@@ -36,6 +36,11 @@
type: String, type: String,
required: true, required: true,
}, },
showDeleteButton: {
type: Boolean,
required: false,
default: true,
},
}, },
components: { components: {
lockedWarning, lockedWarning,
...@@ -81,6 +86,7 @@ ...@@ -81,6 +86,7 @@
:markdown-docs-path="markdownDocsPath" /> :markdown-docs-path="markdownDocsPath" />
<edit-actions <edit-actions
:form-state="formState" :form-state="formState"
:can-destroy="canDestroy" /> :can-destroy="canDestroy"
:show-delete-button="showDeleteButton" />
</form> </form>
</template> </template>
...@@ -35,6 +35,11 @@ export default { ...@@ -35,6 +35,11 @@ export default {
type: String, type: String,
required: false, required: false,
}, },
containerClass: {
type: String,
required: false,
default: 'btn btn-align-content',
},
}, },
components: { components: {
loadingIcon, loadingIcon,
...@@ -49,9 +54,9 @@ export default { ...@@ -49,9 +54,9 @@ export default {
<template> <template>
<button <button
class="btn btn-align-content"
@click="onClick" @click="onClick"
type="button" type="button"
:class="containerClass"
:disabled="loading || disabled" :disabled="loading || disabled"
> >
<transition name="fade"> <transition name="fade">
......
...@@ -353,3 +353,7 @@ ...@@ -353,3 +353,7 @@
display: -webkit-flex; display: -webkit-flex;
display: flex; display: flex;
} }
.flex-right {
margin-left: auto;
}
...@@ -223,23 +223,46 @@ describe('Issuable output', () => { ...@@ -223,23 +223,46 @@ describe('Issuable output', () => {
}); });
}); });
it('closes form on error', (done) => { describe('error when updating', () => {
spyOn(window, 'Flash').and.callThrough(); beforeEach(() => {
spyOn(vm.service, 'updateIssuable').and.callFake(() => new Promise((resolve, reject) => { spyOn(window, 'Flash').and.callThrough();
reject(); spyOn(vm.service, 'updateIssuable').and.callFake(() => new Promise((resolve, reject) => {
})); reject();
}));
});
vm.updateIssuable(); it('closes form on error', (done) => {
vm.updateIssuable();
setTimeout(() => { setTimeout(() => {
expect( expect(
eventHub.$emit, eventHub.$emit,
).toHaveBeenCalledWith('close.form'); ).toHaveBeenCalledWith('close.form');
expect( expect(
window.Flash, window.Flash,
).toHaveBeenCalledWith('Error updating issue'); ).toHaveBeenCalledWith('Error updating issue');
done(); done();
});
});
it('returns the correct error message for issuableType', (done) => {
vm.issuableType = 'merge request';
Vue.nextTick(() => {
vm.updateIssuable();
setTimeout(() => {
expect(
eventHub.$emit,
).toHaveBeenCalledWith('close.form');
expect(
window.Flash,
).toHaveBeenCalledWith('Error updating merge request');
done();
});
});
}); });
}); });
}); });
......
...@@ -61,6 +61,15 @@ describe('Edit Actions components', () => { ...@@ -61,6 +61,15 @@ describe('Edit Actions components', () => {
}); });
}); });
it('should not show delete button if showDeleteButton is false', (done) => {
vm.showDeleteButton = false;
Vue.nextTick(() => {
expect(vm.$el.querySelector('.btn-danger')).toBeNull();
done();
});
});
describe('updateIssuable', () => { describe('updateIssuable', () => {
it('sends update.issauble event when clicking save button', () => { it('sends update.issauble event when clicking save button', () => {
vm.$el.querySelector('.btn-save').click(); vm.$el.querySelector('.btn-save').click();
......
...@@ -66,6 +66,23 @@ describe('LoadingButton', function () { ...@@ -66,6 +66,23 @@ describe('LoadingButton', function () {
}); });
}); });
describe('container class', () => {
it('should default to btn btn-align-content', () => {
vm = mountComponent(LoadingButton, {});
expect(vm.$el.classList.contains('btn')).toEqual(true);
expect(vm.$el.classList.contains('btn-align-content')).toEqual(true);
});
it('should be configurable through props', () => {
vm = mountComponent(LoadingButton, {
containerClass: 'test-class',
});
expect(vm.$el.classList.contains('btn')).toEqual(false);
expect(vm.$el.classList.contains('btn-align-content')).toEqual(false);
expect(vm.$el.classList.contains('test-class')).toEqual(true);
});
});
describe('click callback prop', () => { describe('click callback prop', () => {
it('calls given callback when normal', () => { it('calls given callback when normal', () => {
vm = mountComponent(LoadingButton, { vm = mountComponent(LoadingButton, {
......
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