Changed selector names, address code concerns
This commit is contained in:
parent
d5c0018649
commit
84e01b3e7a
13 changed files with 196 additions and 198 deletions
|
@ -22,7 +22,7 @@
|
|||
},
|
||||
computed: {
|
||||
title() {
|
||||
return sprintf(s__('Milestones|Promote %{title} to group milestone?'), { title: this.milestoneTitle });
|
||||
return sprintf(s__('Milestones|Promote %{milestoneTitle} to group milestone?'), { milestoneTitle: this.milestoneTitle });
|
||||
},
|
||||
text() {
|
||||
return s__(`Milestones|Promoting this milestone will make it available for all projects inside the group.
|
||||
|
@ -35,11 +35,11 @@
|
|||
eventHub.$emit('promoteMilestoneModal.requestStarted', this.url);
|
||||
return axios.post(this.url)
|
||||
.then((response) => {
|
||||
eventHub.$emit('promoteMilestoneModal.requestFinished', { labelUrl: this.url, successful: true });
|
||||
eventHub.$emit('promoteMilestoneModal.requestFinished', { milestoneUrl: this.url, successful: true });
|
||||
redirectTo(response.request.responseURL);
|
||||
})
|
||||
.catch((error) => {
|
||||
eventHub.$emit('promoteMilestoneModal.requestFinished', { labelUrl: this.url, successful: true });
|
||||
eventHub.$emit('promoteMilestoneModal.requestFinished', { milestoneUrl: this.url, successful: false });
|
||||
createFlash(error);
|
||||
});
|
||||
},
|
||||
|
@ -53,11 +53,11 @@
|
|||
:footer-primary-button-text="s__('Milestones|Promote Milestone')"
|
||||
@submit="onSubmit"
|
||||
>
|
||||
<div
|
||||
<template
|
||||
slot="title"
|
||||
>
|
||||
{{ title }}
|
||||
</div>
|
||||
</template>
|
||||
{{ text }}
|
||||
</gl-modal>
|
||||
</template>
|
||||
|
|
|
@ -37,16 +37,14 @@ export default () => {
|
|||
};
|
||||
|
||||
const deleteMilestoneButtons = document.querySelectorAll('.js-delete-milestone-button');
|
||||
for (let i = 0; i < deleteMilestoneButtons.length; i += 1) {
|
||||
const button = deleteMilestoneButtons[i];
|
||||
deleteMilestoneButtons.forEach((button) => {
|
||||
button.addEventListener('click', onDeleteButtonClick);
|
||||
}
|
||||
});
|
||||
|
||||
eventHub.$once('deleteMilestoneModal.mounted', () => {
|
||||
for (let i = 0; i < deleteMilestoneButtons.length; i += 1) {
|
||||
const button = deleteMilestoneButtons[i];
|
||||
deleteMilestoneButtons.forEach((button) => {
|
||||
button.removeAttribute('disabled');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return new Vue({
|
||||
|
|
|
@ -5,8 +5,9 @@ import eventHub from './event_hub';
|
|||
|
||||
Vue.use(Translate);
|
||||
|
||||
export default () => {
|
||||
const onRequestFinished = ({ milestoneUrl, successful }) => {
|
||||
const button = document.querySelector(`.js-promote-project-milestone[data-url="${milestoneUrl}"]`);
|
||||
const button = document.querySelector(`.js-promote-project-milestone-button[data-url="${milestoneUrl}"]`);
|
||||
|
||||
if (!successful) {
|
||||
button.removeAttribute('disabled');
|
||||
|
@ -14,7 +15,7 @@ const onRequestFinished = ({ milestoneUrl, successful }) => {
|
|||
};
|
||||
|
||||
const onRequestStarted = (milestoneUrl) => {
|
||||
const button = document.querySelector(`.js-promote-project-milestone[data-url="${milestoneUrl}"]`);
|
||||
const button = document.querySelector(`.js-promote-project-milestone-button[data-url="${milestoneUrl}"]`);
|
||||
button.setAttribute('disabled', '');
|
||||
eventHub.$once('promoteMilestoneModal.requestFinished', onRequestFinished);
|
||||
};
|
||||
|
@ -29,7 +30,7 @@ const onDeleteButtonClick = (event) => {
|
|||
eventHub.$emit('promoteMilestoneModal.props', modalProps);
|
||||
};
|
||||
|
||||
const promoteMilestoneButtons = document.querySelectorAll('.js-promote-project-milestone');
|
||||
const promoteMilestoneButtons = document.querySelectorAll('.js-promote-project-milestone-button');
|
||||
promoteMilestoneButtons.forEach((button) => {
|
||||
button.addEventListener('click', onDeleteButtonClick);
|
||||
});
|
||||
|
@ -40,9 +41,12 @@ eventHub.$once('promoteMilestoneModal.mounted', () => {
|
|||
});
|
||||
});
|
||||
|
||||
export default () => {
|
||||
const promoteMilestoneComponent = new Vue({
|
||||
el: '#promote-milestone-modal',
|
||||
const promoteMilestoneModal = document.getElementById('promote-milestone-modal');
|
||||
let promoteMilestoneComponent;
|
||||
|
||||
if (promoteMilestoneModal) {
|
||||
promoteMilestoneComponent = new Vue({
|
||||
el: promoteMilestoneModal,
|
||||
components: {
|
||||
PromoteMilestoneModal,
|
||||
},
|
||||
|
@ -72,11 +76,7 @@ export default () => {
|
|||
});
|
||||
},
|
||||
});
|
||||
|
||||
const promoteMilestoneModal = document.getElementById('promote-milestone-modal');
|
||||
let withMilestone;
|
||||
if (promoteMilestoneModal != null) {
|
||||
withMilestone = promoteMilestoneComponent;
|
||||
}
|
||||
return withMilestone;
|
||||
|
||||
return promoteMilestoneComponent;
|
||||
};
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import createFlash from '~/flash';
|
||||
import GlModal from '~/vue_shared/components/gl_modal.vue';
|
||||
import { redirectTo } from '~/lib/utils/url_utility';
|
||||
import { s__ } from '~/locale';
|
||||
import { s__, sprintf } from '~/locale';
|
||||
import eventHub from '../event_hub';
|
||||
|
||||
export default {
|
||||
|
@ -23,12 +23,26 @@
|
|||
type: String,
|
||||
required: true,
|
||||
},
|
||||
labelTextColor: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
text() {
|
||||
return s__(`Milestones|Promoting this label will make it available for all projects inside the group.
|
||||
Existing project labels with the same name will be merged. This action cannot be reversed.`);
|
||||
},
|
||||
title() {
|
||||
const label = `<span
|
||||
class="label color-label"
|
||||
style="background-color: ${this.labelColor}; color: ${this.labelTextColor};"
|
||||
>${this.labelTitle}</span>`;
|
||||
|
||||
return sprintf(s__('Labels|Promote label %{labelTitle} to Group Label?'), {
|
||||
labelTitle: label,
|
||||
}, false);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onSubmit() {
|
||||
|
@ -55,15 +69,9 @@
|
|||
>
|
||||
<div
|
||||
slot="title"
|
||||
v-html="title"
|
||||
>
|
||||
{{ s__('Labels|Promote label') }}
|
||||
<span
|
||||
class="label color-label"
|
||||
:style="{ backgroundColor: labelColor }"
|
||||
>
|
||||
{{ labelTitle }}
|
||||
</span>
|
||||
{{ s__('Labels|to Group Label?') }}
|
||||
{{ title }}
|
||||
</div>
|
||||
|
||||
{{ text }}
|
||||
|
|
|
@ -6,8 +6,11 @@ import PromoteLabelModal from '../components/promote_label_modal.vue';
|
|||
|
||||
Vue.use(Translate);
|
||||
|
||||
const initLabelIndex = () => {
|
||||
initLabels();
|
||||
|
||||
const onRequestFinished = ({ labelUrl, successful }) => {
|
||||
const button = document.querySelector(`.js-promote-project-label[data-url="${labelUrl}"]`);
|
||||
const button = document.querySelector(`.js-promote-project-label-button[data-url="${labelUrl}"]`);
|
||||
|
||||
if (!successful) {
|
||||
button.removeAttribute('disabled');
|
||||
|
@ -15,7 +18,7 @@ const onRequestFinished = ({ labelUrl, successful }) => {
|
|||
};
|
||||
|
||||
const onRequestStarted = (labelUrl) => {
|
||||
const button = document.querySelector(`.js-promote-project-label[data-url="${labelUrl}"]`);
|
||||
const button = document.querySelector(`.js-promote-project-label-button[data-url="${labelUrl}"]`);
|
||||
button.setAttribute('disabled', '');
|
||||
eventHub.$once('promoteLabelModal.requestFinished', onRequestFinished);
|
||||
};
|
||||
|
@ -25,13 +28,14 @@ const onDeleteButtonClick = (event) => {
|
|||
const modalProps = {
|
||||
labelTitle: button.dataset.labelTitle,
|
||||
labelColor: button.dataset.labelColor,
|
||||
labelTextColor: button.dataset.labelTextColor,
|
||||
url: button.dataset.url,
|
||||
};
|
||||
eventHub.$once('promoteLabelModal.requestStarted', onRequestStarted);
|
||||
eventHub.$emit('promoteLabelModal.props', modalProps);
|
||||
};
|
||||
|
||||
const promoteLabelButtons = document.querySelectorAll('.js-promote-project-label');
|
||||
const promoteLabelButtons = document.querySelectorAll('.js-promote-project-label-button');
|
||||
promoteLabelButtons.forEach((button) => {
|
||||
button.addEventListener('click', onDeleteButtonClick);
|
||||
});
|
||||
|
@ -42,11 +46,12 @@ eventHub.$once('promoteLabelModal.mounted', () => {
|
|||
});
|
||||
});
|
||||
|
||||
const initLabelIndex = () => {
|
||||
initLabels();
|
||||
const promoteLabelModal = document.getElementById('promote-label-modal');
|
||||
let promoteLabelModalComponent;
|
||||
|
||||
const promoteLabelModalComponent = new Vue({
|
||||
el: '#promote-label-modal',
|
||||
if (promoteLabelModal) {
|
||||
promoteLabelModalComponent = new Vue({
|
||||
el: promoteLabelModal,
|
||||
components: {
|
||||
PromoteLabelModal,
|
||||
},
|
||||
|
@ -55,6 +60,7 @@ const initLabelIndex = () => {
|
|||
modalProps: {
|
||||
labelTitle: '',
|
||||
labelColor: '',
|
||||
labelTextColor: '',
|
||||
url: '',
|
||||
},
|
||||
};
|
||||
|
@ -77,13 +83,9 @@ const initLabelIndex = () => {
|
|||
});
|
||||
},
|
||||
});
|
||||
|
||||
const promoteLabelModal = document.getElementById('promote-label-modal');
|
||||
let withLabel;
|
||||
if (promoteLabelModal != null) {
|
||||
withLabel = promoteLabelModalComponent;
|
||||
}
|
||||
return withLabel;
|
||||
|
||||
return promoteLabelModalComponent;
|
||||
};
|
||||
|
||||
document.addEventListener('DOMContentLoaded', initLabelIndex);
|
||||
|
|
|
@ -4,13 +4,15 @@
|
|||
|
||||
.page-title,
|
||||
.modal-title {
|
||||
margin-top: 0;
|
||||
|
||||
.color-label {
|
||||
font-size: $gl-font-size;
|
||||
padding: $gl-vert-padding $label-padding-modal;
|
||||
}
|
||||
}
|
||||
|
||||
.page-title {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
- hide_class = ''
|
||||
- can_admin_label = can?(current_user, :admin_label, @project)
|
||||
|
||||
#promote-label-modal
|
||||
- if @labels.exists? || @prioritized_labels.exists?
|
||||
#promote-label-modal
|
||||
%div{ class: container_class }
|
||||
.top-area.adjust
|
||||
.nav-text
|
||||
|
|
|
@ -27,12 +27,12 @@
|
|||
Edit
|
||||
|
||||
- if @project.group
|
||||
%button.js-promote-project-milestone.btn.btn-grouped{ data: { toggle: 'modal',
|
||||
%button.js-promote-project-milestone-button.btn.btn-grouped{ data: { toggle: 'modal',
|
||||
target: '#promote-milestone-modal',
|
||||
milestone_title: @milestone.title,
|
||||
url: promote_project_milestone_path(@milestone.project, @milestone),
|
||||
container: 'body',
|
||||
disabled: true } }
|
||||
container: 'body' },
|
||||
disabled: true }
|
||||
= _('Promote')
|
||||
#promote-milestone-modal
|
||||
|
||||
|
|
|
@ -48,10 +48,11 @@
|
|||
|
||||
.pull-right.hidden-xs.hidden-sm
|
||||
- if label.is_a?(ProjectLabel) && label.project.group && can?(current_user, :admin_label, label.project.group)
|
||||
%a.js-promote-project-label.btn.btn-transparent.btn-action.has-tooltip{ title: _('Promote to Group Label'),
|
||||
%a.js-promote-project-label-button.btn.btn-transparent.btn-action.has-tooltip{ title: _('Promote to Group Label'),
|
||||
data: { url: promote_project_label_path(label.project, label),
|
||||
label_title: label.title,
|
||||
label_color: label.color,
|
||||
label_text_color: label.text_color,
|
||||
target: '#promote-label-modal',
|
||||
container: 'body',
|
||||
toggle: 'modal' },
|
||||
|
|
|
@ -51,14 +51,14 @@
|
|||
\
|
||||
|
||||
- if @project.group
|
||||
%a.js-promote-project-milestone.btn.btn-xs.btn-grouped.has-tooltip{ title: _('Promote to Group Milestone'),
|
||||
%a.js-promote-project-milestone-button.btn.btn-xs.btn-grouped.has-tooltip{ title: _('Promote to Group Milestone'),
|
||||
data: { url: promote_project_milestone_path(milestone.project, milestone),
|
||||
milestone_title: milestone.title,
|
||||
target: '#promote-milestone-modal',
|
||||
container: 'body',
|
||||
toggle: 'modal' },
|
||||
disabled: true }
|
||||
Promote
|
||||
= _('Promote')
|
||||
|
||||
= link_to 'Close Milestone', project_milestone_path(@project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-xs btn-close btn-grouped"
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
title: Added vue based promotion modals for labels and milestones
|
||||
title: Added new design for promotion modals
|
||||
merge_request: 17197
|
||||
author:
|
||||
type: other
|
||||
|
|
|
@ -7,35 +7,28 @@ import mountComponent from '../../../helpers/vue_mount_component_helper';
|
|||
|
||||
describe('Promote label modal', () => {
|
||||
let vm;
|
||||
let Component;
|
||||
const Component = Vue.extend(promoteLabelModal);
|
||||
const labelMockData = {
|
||||
labelTitle: 'Documentation',
|
||||
labelColor: '#5cb85c',
|
||||
url: `${gl.TEST_HOST}/dummy/endpoint`,
|
||||
labelTextColor: '#ffffff',
|
||||
url: `${gl.TEST_HOST}/dummy/promote/labels`,
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
Component = Vue.extend(promoteLabelModal);
|
||||
});
|
||||
|
||||
describe('Modal title and description', () => {
|
||||
beforeEach(() => {
|
||||
vm = mountComponent(Component, {
|
||||
...labelMockData,
|
||||
});
|
||||
vm = mountComponent(Component, labelMockData);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vm.$destroy();
|
||||
});
|
||||
|
||||
it('should contain the proper description', () => {
|
||||
it('contains the proper description', () => {
|
||||
expect(vm.text).toContain('Promoting this label will make it available for all projects inside the group');
|
||||
expect(vm.text).toContain('Existing project labels with the same name will be merged');
|
||||
expect(vm.text).toContain('This action cannot be reversed.');
|
||||
});
|
||||
|
||||
it('should contain a label span with the color', () => {
|
||||
it('contains a label span with the color', () => {
|
||||
const labelFromTitle = vm.$el.querySelector('.modal-header .label.color-label');
|
||||
|
||||
expect(labelFromTitle.style.backgroundColor).not.toBe(null);
|
||||
|
@ -55,7 +48,7 @@ describe('Promote label modal', () => {
|
|||
vm.$destroy();
|
||||
});
|
||||
|
||||
it('should redirect when a label is promoted', (done) => {
|
||||
it('redirects when a label is promoted', (done) => {
|
||||
const responseURL = `${gl.TEST_HOST}/dummy/endpoint`;
|
||||
spyOn(axios, 'post').and.callFake((url) => {
|
||||
expect(url).toBe(labelMockData.url);
|
||||
|
@ -71,6 +64,7 @@ describe('Promote label modal', () => {
|
|||
vm.onSubmit()
|
||||
.then(() => {
|
||||
expect(redirectSpy).toHaveBeenCalledWith(responseURL);
|
||||
expect(eventHub.$emit).toHaveBeenCalledWith('promoteLabelModal.requestFinished', { labelUrl: labelMockData.url, successful: true });
|
||||
})
|
||||
.then(done)
|
||||
.catch(done.fail);
|
||||
|
|
|
@ -7,34 +7,26 @@ import mountComponent from '../../../../helpers/vue_mount_component_helper';
|
|||
|
||||
describe('Promote milestone modal', () => {
|
||||
let vm;
|
||||
let Component;
|
||||
const Component = Vue.extend(promoteMilestoneModal);
|
||||
const milestoneMockData = {
|
||||
milestoneTitle: 'v1.0',
|
||||
url: `${gl.TEST_HOST}/dummy/endpoint`,
|
||||
url: `${gl.TEST_HOST}/dummy/promote/milestones`,
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
Component = Vue.extend(promoteMilestoneModal);
|
||||
});
|
||||
|
||||
describe('Modal title and description', () => {
|
||||
beforeEach(() => {
|
||||
vm = mountComponent(Component, {
|
||||
...milestoneMockData,
|
||||
});
|
||||
vm = mountComponent(Component, milestoneMockData);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vm.$destroy();
|
||||
});
|
||||
|
||||
it('should contain the proper description', () => {
|
||||
it('contains the proper description', () => {
|
||||
expect(vm.text).toContain('Promoting this milestone will make it available for all projects inside the group.');
|
||||
expect(vm.text).toContain('Existing project milestones with the same name will be merged.');
|
||||
expect(vm.text).toContain('This action cannot be reversed.');
|
||||
});
|
||||
|
||||
it('should contain the correct title', () => {
|
||||
it('contains the correct title', () => {
|
||||
expect(vm.title).toEqual('Promote v1.0 to group milestone?');
|
||||
});
|
||||
});
|
||||
|
@ -51,7 +43,7 @@ describe('Promote milestone modal', () => {
|
|||
vm.$destroy();
|
||||
});
|
||||
|
||||
it('should redirect when a milestone is promoted', (done) => {
|
||||
it('redirects when a milestone is promoted', (done) => {
|
||||
const responseURL = `${gl.TEST_HOST}/dummy/endpoint`;
|
||||
spyOn(axios, 'post').and.callFake((url) => {
|
||||
expect(url).toBe(milestoneMockData.url);
|
||||
|
@ -67,6 +59,7 @@ describe('Promote milestone modal', () => {
|
|||
vm.onSubmit()
|
||||
.then(() => {
|
||||
expect(redirectSpy).toHaveBeenCalledWith(responseURL);
|
||||
expect(eventHub.$emit).toHaveBeenCalledWith('promoteMilestoneModal.requestFinished', { milestoneUrl: milestoneMockData.url, successful: true });
|
||||
})
|
||||
.then(done)
|
||||
.catch(done.fail);
|
||||
|
|
Loading…
Reference in a new issue