Skip to content
Snippets Groups Projects
Commit 84e01b3e authored by Jose Ivan Vargas Lopez's avatar Jose Ivan Vargas Lopez
Browse files

Changed selector names, address code concerns

parent d5c00186
No related branches found
No related tags found
No related merge requests found
Showing
with 183 additions and 185 deletions
Loading
Loading
@@ -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.
Loading
Loading
@@ -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);
});
},
Loading
Loading
@@ -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>
Loading
Loading
Loading
Loading
@@ -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({
Loading
Loading
Loading
Loading
@@ -5,78 +5,78 @@ import eventHub from './event_hub';
 
Vue.use(Translate);
 
const onRequestFinished = ({ milestoneUrl, successful }) => {
const button = document.querySelector(`.js-promote-project-milestone[data-url="${milestoneUrl}"]`);
if (!successful) {
button.removeAttribute('disabled');
}
};
export default () => {
const onRequestFinished = ({ milestoneUrl, successful }) => {
const button = document.querySelector(`.js-promote-project-milestone-button[data-url="${milestoneUrl}"]`);
 
const onRequestStarted = (milestoneUrl) => {
const button = document.querySelector(`.js-promote-project-milestone[data-url="${milestoneUrl}"]`);
button.setAttribute('disabled', '');
eventHub.$once('promoteMilestoneModal.requestFinished', onRequestFinished);
};
if (!successful) {
button.removeAttribute('disabled');
}
};
 
const onDeleteButtonClick = (event) => {
const button = event.currentTarget;
const modalProps = {
milestoneTitle: button.dataset.milestoneTitle,
url: button.dataset.url,
const onRequestStarted = (milestoneUrl) => {
const button = document.querySelector(`.js-promote-project-milestone-button[data-url="${milestoneUrl}"]`);
button.setAttribute('disabled', '');
eventHub.$once('promoteMilestoneModal.requestFinished', onRequestFinished);
};
eventHub.$once('promoteMilestoneModal.requestStarted', onRequestStarted);
eventHub.$emit('promoteMilestoneModal.props', modalProps);
};
 
const promoteMilestoneButtons = document.querySelectorAll('.js-promote-project-milestone');
promoteMilestoneButtons.forEach((button) => {
button.addEventListener('click', onDeleteButtonClick);
});
const onDeleteButtonClick = (event) => {
const button = event.currentTarget;
const modalProps = {
milestoneTitle: button.dataset.milestoneTitle,
url: button.dataset.url,
};
eventHub.$once('promoteMilestoneModal.requestStarted', onRequestStarted);
eventHub.$emit('promoteMilestoneModal.props', modalProps);
};
 
eventHub.$once('promoteMilestoneModal.mounted', () => {
const promoteMilestoneButtons = document.querySelectorAll('.js-promote-project-milestone-button');
promoteMilestoneButtons.forEach((button) => {
button.removeAttribute('disabled');
button.addEventListener('click', onDeleteButtonClick);
});
});
 
export default () => {
const promoteMilestoneComponent = new Vue({
el: '#promote-milestone-modal',
components: {
PromoteMilestoneModal,
},
data() {
return {
modalProps: {
milestoneTitle: '',
url: '',
},
};
},
mounted() {
eventHub.$on('promoteMilestoneModal.props', this.setModalProps);
eventHub.$emit('promoteMilestoneModal.mounted');
},
beforeDestroy() {
eventHub.$off('promoteMilestoneModal.props', this.setModalProps);
},
methods: {
setModalProps(modalProps) {
this.modalProps = modalProps;
},
},
render(createElement) {
return createElement('promote-milestone-modal', {
props: this.modalProps,
});
},
eventHub.$once('promoteMilestoneModal.mounted', () => {
promoteMilestoneButtons.forEach((button) => {
button.removeAttribute('disabled');
});
});
 
const promoteMilestoneModal = document.getElementById('promote-milestone-modal');
let withMilestone;
if (promoteMilestoneModal != null) {
withMilestone = promoteMilestoneComponent;
let promoteMilestoneComponent;
if (promoteMilestoneModal) {
promoteMilestoneComponent = new Vue({
el: promoteMilestoneModal,
components: {
PromoteMilestoneModal,
},
data() {
return {
modalProps: {
milestoneTitle: '',
url: '',
},
};
},
mounted() {
eventHub.$on('promoteMilestoneModal.props', this.setModalProps);
eventHub.$emit('promoteMilestoneModal.mounted');
},
beforeDestroy() {
eventHub.$off('promoteMilestoneModal.props', this.setModalProps);
},
methods: {
setModalProps(modalProps) {
this.modalProps = modalProps;
},
},
render(createElement) {
return createElement('promote-milestone-modal', {
props: this.modalProps,
});
},
});
}
return withMilestone;
return promoteMilestoneComponent;
};
Loading
Loading
@@ -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 {
Loading
Loading
@@ -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() {
Loading
Loading
@@ -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 }}
Loading
Loading
Loading
Loading
@@ -6,84 +6,86 @@ import PromoteLabelModal from '../components/promote_label_modal.vue';
 
Vue.use(Translate);
 
const onRequestFinished = ({ labelUrl, successful }) => {
const button = document.querySelector(`.js-promote-project-label[data-url="${labelUrl}"]`);
const initLabelIndex = () => {
initLabels();
 
if (!successful) {
button.removeAttribute('disabled');
}
};
const onRequestFinished = ({ labelUrl, successful }) => {
const button = document.querySelector(`.js-promote-project-label-button[data-url="${labelUrl}"]`);
 
const onRequestStarted = (labelUrl) => {
const button = document.querySelector(`.js-promote-project-label[data-url="${labelUrl}"]`);
button.setAttribute('disabled', '');
eventHub.$once('promoteLabelModal.requestFinished', onRequestFinished);
};
if (!successful) {
button.removeAttribute('disabled');
}
};
 
const onDeleteButtonClick = (event) => {
const button = event.currentTarget;
const modalProps = {
labelTitle: button.dataset.labelTitle,
labelColor: button.dataset.labelColor,
url: button.dataset.url,
const onRequestStarted = (labelUrl) => {
const button = document.querySelector(`.js-promote-project-label-button[data-url="${labelUrl}"]`);
button.setAttribute('disabled', '');
eventHub.$once('promoteLabelModal.requestFinished', onRequestFinished);
};
eventHub.$once('promoteLabelModal.requestStarted', onRequestStarted);
eventHub.$emit('promoteLabelModal.props', modalProps);
};
 
const promoteLabelButtons = document.querySelectorAll('.js-promote-project-label');
promoteLabelButtons.forEach((button) => {
button.addEventListener('click', onDeleteButtonClick);
});
const onDeleteButtonClick = (event) => {
const button = event.currentTarget;
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);
};
 
eventHub.$once('promoteLabelModal.mounted', () => {
const promoteLabelButtons = document.querySelectorAll('.js-promote-project-label-button');
promoteLabelButtons.forEach((button) => {
button.removeAttribute('disabled');
button.addEventListener('click', onDeleteButtonClick);
});
});
const initLabelIndex = () => {
initLabels();
 
const promoteLabelModalComponent = new Vue({
el: '#promote-label-modal',
components: {
PromoteLabelModal,
},
data() {
return {
modalProps: {
labelTitle: '',
labelColor: '',
url: '',
},
};
},
mounted() {
eventHub.$on('promoteLabelModal.props', this.setModalProps);
eventHub.$emit('promoteLabelModal.mounted');
},
beforeDestroy() {
eventHub.$off('promoteLabelModal.props', this.setModalProps);
},
methods: {
setModalProps(modalProps) {
this.modalProps = modalProps;
},
},
render(createElement) {
return createElement('promote-label-modal', {
props: this.modalProps,
});
},
eventHub.$once('promoteLabelModal.mounted', () => {
promoteLabelButtons.forEach((button) => {
button.removeAttribute('disabled');
});
});
 
const promoteLabelModal = document.getElementById('promote-label-modal');
let withLabel;
if (promoteLabelModal != null) {
withLabel = promoteLabelModalComponent;
let promoteLabelModalComponent;
if (promoteLabelModal) {
promoteLabelModalComponent = new Vue({
el: promoteLabelModal,
components: {
PromoteLabelModal,
},
data() {
return {
modalProps: {
labelTitle: '',
labelColor: '',
labelTextColor: '',
url: '',
},
};
},
mounted() {
eventHub.$on('promoteLabelModal.props', this.setModalProps);
eventHub.$emit('promoteLabelModal.mounted');
},
beforeDestroy() {
eventHub.$off('promoteLabelModal.props', this.setModalProps);
},
methods: {
setModalProps(modalProps) {
this.modalProps = modalProps;
},
},
render(createElement) {
return createElement('promote-label-modal', {
props: this.modalProps,
});
},
});
}
return withLabel;
return promoteLabelModalComponent;
};
 
document.addEventListener('DOMContentLoaded', initLabelIndex);
Loading
Loading
@@ -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 {
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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
 
Loading
Loading
Loading
Loading
@@ -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' },
Loading
Loading
Loading
Loading
@@ -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"
 
Loading
Loading
---
title: Added vue based promotion modals for labels and milestones
title: Added new design for promotion modals
merge_request: 17197
author:
type: other
Loading
Loading
@@ -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);
Loading
Loading
@@ -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);
Loading
Loading
@@ -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);
Loading
Loading
Loading
Loading
@@ -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?');
});
});
Loading
Loading
@@ -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);
Loading
Loading
@@ -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
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment