Add id to modal.vue to support data-toggle="modal"
This commit is contained in:
parent
b1e1990ee2
commit
2c47f0924f
|
@ -45,11 +45,9 @@ export default {
|
|||
onLeaveGroup() {
|
||||
this.modalStatus = true;
|
||||
},
|
||||
leaveGroup(leaveConfirmed) {
|
||||
leaveGroup() {
|
||||
this.modalStatus = false;
|
||||
if (leaveConfirmed) {
|
||||
eventHub.$emit('leaveGroup', this.group, this.parentGroup);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -32,10 +32,10 @@
|
|||
methods: {
|
||||
createNewItem(type) {
|
||||
this.modalType = type;
|
||||
this.toggleModalOpen();
|
||||
this.openModal = true;
|
||||
},
|
||||
toggleModalOpen() {
|
||||
this.openModal = !this.openModal;
|
||||
hideModal() {
|
||||
this.openModal = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -95,7 +95,7 @@
|
|||
:branch-id="branch"
|
||||
:path="path"
|
||||
:parent="parent"
|
||||
@toggle="toggleModalOpen"
|
||||
@hide="hideModal"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -43,10 +43,10 @@
|
|||
type: this.type,
|
||||
});
|
||||
|
||||
this.toggleModalOpen();
|
||||
this.hideModal();
|
||||
},
|
||||
toggleModalOpen() {
|
||||
this.$emit('toggle');
|
||||
hideModal() {
|
||||
this.$emit('hide');
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
|
@ -86,7 +86,7 @@
|
|||
:title="modalTitle"
|
||||
:primary-button-label="buttonLabel"
|
||||
kind="success"
|
||||
@toggle="toggleModalOpen"
|
||||
@cancel="hideModal"
|
||||
@submit="createEntryInStore"
|
||||
>
|
||||
<form
|
||||
|
|
|
@ -110,7 +110,7 @@ export default {
|
|||
kind="primary"
|
||||
:title="__('Branch has changed')"
|
||||
:text="__('This branch has changed since you started editing. Would you like to create a new branch?')"
|
||||
@toggle="showNewBranchModal = false"
|
||||
@cancel="showNewBranchModal = false"
|
||||
@submit="makeCommit(true)"
|
||||
/>
|
||||
<commit-files-list
|
||||
|
|
|
@ -50,7 +50,7 @@ export default {
|
|||
kind="warning"
|
||||
:title="__('Are you sure?')"
|
||||
:text="__('Are you sure you want to discard your changes?')"
|
||||
@toggle="closeDiscardPopup"
|
||||
@cancel="closeDiscardPopup"
|
||||
@submit="toggleEditMode(true)"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script>
|
||||
import modal from '../../../vue_shared/components/modal.vue';
|
||||
import { __, s__, sprintf } from '../../../locale';
|
||||
import csrf from '../../../lib/utils/csrf';
|
||||
import modal from '~/vue_shared/components/modal.vue';
|
||||
import { __, s__, sprintf } from '~/locale';
|
||||
import csrf from '~/lib/utils/csrf';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
|
@ -22,7 +22,6 @@
|
|||
return {
|
||||
enteredPassword: '',
|
||||
enteredUsername: '',
|
||||
isOpen: false,
|
||||
};
|
||||
},
|
||||
components: {
|
||||
|
@ -69,34 +68,22 @@ Once you confirm %{deleteAccount}, it cannot be undone or recovered.`),
|
|||
|
||||
return this.enteredUsername === this.username;
|
||||
},
|
||||
onSubmit(status) {
|
||||
if (status) {
|
||||
if (!this.canSubmit()) {
|
||||
return;
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
this.$refs.form.submit();
|
||||
}
|
||||
|
||||
this.toggleOpen(false);
|
||||
},
|
||||
toggleOpen(isOpen) {
|
||||
this.isOpen = isOpen;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<modal
|
||||
v-if="isOpen"
|
||||
id="delete-account-modal"
|
||||
:title="s__('Profiles|Delete your account?')"
|
||||
:text="text"
|
||||
:kind="`danger ${!canSubmit() && 'disabled'}`"
|
||||
kind="danger"
|
||||
:primary-button-label="s__('Profiles|Delete account')"
|
||||
@toggle="toggleOpen"
|
||||
@submit="onSubmit">
|
||||
@submit="onSubmit"
|
||||
:submit-disabled="!canSubmit()">
|
||||
|
||||
<template slot="body" slot-scope="props">
|
||||
<p v-html="props.text"></p>
|
||||
|
@ -135,12 +122,4 @@ Once you confirm %{deleteAccount}, it cannot be undone or recovered.`),
|
|||
</template>
|
||||
|
||||
</modal>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-danger"
|
||||
@click="toggleOpen(true)">
|
||||
{{ s__('Profiles|Delete account') }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
import Vue from 'vue';
|
||||
|
||||
import Translate from '~/vue_shared/translate';
|
||||
|
||||
import deleteAccountModal from './components/delete_account_modal.vue';
|
||||
|
||||
Vue.use(Translate);
|
||||
|
||||
const deleteAccountButton = document.getElementById('delete-account-button');
|
||||
const deleteAccountModalEl = document.getElementById('delete-account-modal');
|
||||
// eslint-disable-next-line no-new
|
||||
new Vue({
|
||||
|
@ -9,6 +14,9 @@ new Vue({
|
|||
components: {
|
||||
deleteAccountModal,
|
||||
},
|
||||
mounted() {
|
||||
deleteAccountButton.classList.remove('disabled');
|
||||
},
|
||||
render(createElement) {
|
||||
return createElement('delete-account-modal', {
|
||||
props: {
|
||||
|
|
|
@ -3,6 +3,10 @@ export default {
|
|||
name: 'modal',
|
||||
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
required: false,
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
required: false,
|
||||
|
@ -62,11 +66,11 @@ export default {
|
|||
},
|
||||
|
||||
methods: {
|
||||
close() {
|
||||
this.$emit('toggle', false);
|
||||
emitCancel(event) {
|
||||
this.$emit('cancel', event);
|
||||
},
|
||||
emitSubmit(status) {
|
||||
this.$emit('submit', status);
|
||||
emitSubmit(event) {
|
||||
this.$emit('submit', event);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -75,7 +79,9 @@ export default {
|
|||
<template>
|
||||
<div class="modal-open">
|
||||
<div
|
||||
class="modal show"
|
||||
:id="id"
|
||||
class="modal"
|
||||
:class="id ? '' : 'show'"
|
||||
role="dialog"
|
||||
tabindex="-1"
|
||||
>
|
||||
|
@ -93,7 +99,8 @@ export default {
|
|||
<button
|
||||
type="button"
|
||||
class="close pull-right"
|
||||
@click="close"
|
||||
@click="emitCancel($event)"
|
||||
data-dismiss="modal"
|
||||
aria-label="Close"
|
||||
>
|
||||
<span aria-hidden="true">×</span>
|
||||
|
@ -110,7 +117,8 @@ export default {
|
|||
type="button"
|
||||
class="btn pull-left"
|
||||
:class="btnCancelKindClass"
|
||||
@click="close">
|
||||
@click="emitCancel($event)"
|
||||
data-dismiss="modal">
|
||||
{{ closeButtonLabel }}
|
||||
</button>
|
||||
<button
|
||||
|
@ -119,13 +127,17 @@ export default {
|
|||
class="btn pull-right js-primary-button"
|
||||
:disabled="submitDisabled"
|
||||
:class="btnKindClass"
|
||||
@click="emitSubmit(true)">
|
||||
@click="emitSubmit($event)"
|
||||
data-dismiss="modal">
|
||||
{{ primaryButtonLabel }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-backdrop fade in" />
|
||||
<div
|
||||
v-if="!id"
|
||||
class="modal-backdrop fade in">
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -70,7 +70,7 @@ export default {
|
|||
class="recaptcha-modal js-recaptcha-modal"
|
||||
:hide-footer="true"
|
||||
:title="__('Please solve the reCAPTCHA')"
|
||||
@toggle="close"
|
||||
@cancel="close"
|
||||
>
|
||||
<div slot="body">
|
||||
<p>
|
||||
|
|
|
@ -84,11 +84,13 @@
|
|||
= s_('Profiles|Deleting an account has the following effects:')
|
||||
= render 'users/deletion_guidance', user: current_user
|
||||
|
||||
%button#delete-account-button.btn.btn-danger.disabled{ data: { toggle: 'modal',
|
||||
target: '#delete-account-modal' } }
|
||||
= s_('Profiles|Delete account')
|
||||
|
||||
#delete-account-modal{ data: { action_url: user_registration_path,
|
||||
confirm_with_password: ('true' if current_user.confirm_deletion_with_password?),
|
||||
username: current_user.username } }
|
||||
%button.btn.btn-danger.disabled
|
||||
= s_('Profiles|Delete account')
|
||||
- else
|
||||
- if @user.solo_owned_groups.present?
|
||||
%p
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add id to modal.vue to support data-toggle="modal"
|
||||
merge_request: 16189
|
||||
author:
|
||||
type: other
|
|
@ -47,18 +47,12 @@ describe('ItemActionsComponent', () => {
|
|||
it('should change `modalStatus` prop to `false` and emit `leaveGroup` event with required params when called with `leaveConfirmed` as `true`', () => {
|
||||
spyOn(eventHub, '$emit');
|
||||
vm.modalStatus = true;
|
||||
vm.leaveGroup(true);
|
||||
|
||||
vm.leaveGroup();
|
||||
|
||||
expect(vm.modalStatus).toBeFalsy();
|
||||
expect(eventHub.$emit).toHaveBeenCalledWith('leaveGroup', vm.group, vm.parentGroup);
|
||||
});
|
||||
|
||||
it('should change `modalStatus` prop to `false` and should NOT emit `leaveGroup` event when called with `leaveConfirmed` as `false`', () => {
|
||||
spyOn(eventHub, '$emit');
|
||||
vm.modalStatus = true;
|
||||
vm.leaveGroup(false);
|
||||
expect(vm.modalStatus).toBeFalsy();
|
||||
expect(eventHub.$emit).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ describe('DeleteAccountModal component', () => {
|
|||
Vue.nextTick()
|
||||
.then(() => {
|
||||
expect(vm.enteredPassword).toBe(input.value);
|
||||
expect(submitButton).toHaveClass('disabled');
|
||||
expect(submitButton).toHaveAttr('disabled', 'disabled');
|
||||
submitButton.click();
|
||||
expect(form.submit).not.toHaveBeenCalled();
|
||||
})
|
||||
|
@ -68,7 +68,7 @@ describe('DeleteAccountModal component', () => {
|
|||
Vue.nextTick()
|
||||
.then(() => {
|
||||
expect(vm.enteredPassword).toBe(input.value);
|
||||
expect(submitButton).not.toHaveClass('disabled');
|
||||
expect(submitButton).not.toHaveAttr('disabled', 'disabled');
|
||||
submitButton.click();
|
||||
expect(form.submit).toHaveBeenCalled();
|
||||
})
|
||||
|
@ -101,7 +101,7 @@ describe('DeleteAccountModal component', () => {
|
|||
Vue.nextTick()
|
||||
.then(() => {
|
||||
expect(vm.enteredUsername).toBe(input.value);
|
||||
expect(submitButton).toHaveClass('disabled');
|
||||
expect(submitButton).toHaveAttr('disabled', 'disabled');
|
||||
submitButton.click();
|
||||
expect(form.submit).not.toHaveBeenCalled();
|
||||
})
|
||||
|
@ -118,7 +118,7 @@ describe('DeleteAccountModal component', () => {
|
|||
Vue.nextTick()
|
||||
.then(() => {
|
||||
expect(vm.enteredUsername).toBe(input.value);
|
||||
expect(submitButton).not.toHaveClass('disabled');
|
||||
expect(submitButton).not.toHaveAttr('disabled', 'disabled');
|
||||
submitButton.click();
|
||||
expect(form.submit).toHaveBeenCalled();
|
||||
})
|
||||
|
|
|
@ -57,15 +57,16 @@ describe('new dropdown component', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('toggleModalOpen', () => {
|
||||
describe('hideModal', () => {
|
||||
beforeAll((done) => {
|
||||
vm.openModal = true;
|
||||
Vue.nextTick(done);
|
||||
});
|
||||
|
||||
it('closes modal after toggling', (done) => {
|
||||
vm.toggleModalOpen();
|
||||
vm.hideModal();
|
||||
|
||||
Vue.nextTick()
|
||||
.then(() => {
|
||||
expect(vm.$el.querySelector('.modal')).not.toBeNull();
|
||||
})
|
||||
.then(vm.toggleModalOpen)
|
||||
.then(() => {
|
||||
expect(vm.$el.querySelector('.modal')).toBeNull();
|
||||
})
|
||||
|
|
|
@ -2,11 +2,65 @@ import Vue from 'vue';
|
|||
import modal from '~/vue_shared/components/modal.vue';
|
||||
import mountComponent from '../../helpers/vue_mount_component_helper';
|
||||
|
||||
describe('Modal', () => {
|
||||
it('does not render a primary button if no primaryButtonLabel', () => {
|
||||
const modalComponent = Vue.extend(modal);
|
||||
const vm = mountComponent(modalComponent);
|
||||
|
||||
describe('Modal', () => {
|
||||
let vm;
|
||||
|
||||
afterEach(() => {
|
||||
vm.$destroy();
|
||||
});
|
||||
|
||||
describe('props', () => {
|
||||
describe('without primaryButtonLabel', () => {
|
||||
beforeEach(() => {
|
||||
vm = mountComponent(modalComponent, {
|
||||
primaryButtonLabel: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('does not render a primary button', () => {
|
||||
expect(vm.$el.querySelector('.js-primary-button')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('with id', () => {
|
||||
it('does not render a primary button', () => {
|
||||
beforeEach(() => {
|
||||
vm = mountComponent(modalComponent, {
|
||||
id: 'my-modal',
|
||||
});
|
||||
});
|
||||
|
||||
it('assigns the id to the modal', () => {
|
||||
expect(vm.$el.querySelector('#my-modal.modal')).not.toBeNull();
|
||||
});
|
||||
|
||||
it('does not show the modal immediately', () => {
|
||||
expect(vm.$el.querySelector('#my-modal.modal')).not.toHaveClass('show');
|
||||
});
|
||||
|
||||
it('does not show a backdrop', () => {
|
||||
expect(vm.$el.querySelector('modal-backdrop')).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('works with data-toggle="modal"', (done) => {
|
||||
setFixtures(`
|
||||
<button id="modal-button" data-toggle="modal" data-target="#my-modal"></button>
|
||||
<div id="modal-container"></div>
|
||||
`);
|
||||
|
||||
const modalContainer = document.getElementById('modal-container');
|
||||
const modalButton = document.getElementById('modal-button');
|
||||
vm = mountComponent(modalComponent, {
|
||||
id: 'my-modal',
|
||||
}, modalContainer);
|
||||
const modalElement = vm.$el.querySelector('#my-modal');
|
||||
$(modalElement).on('shown.bs.modal', () => done());
|
||||
|
||||
modalButton.click();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue