Commit c4680ce3 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch 'rjain-epic-trees' into 'master'

Epic tree bug fixes

See merge request gitlab-org/gitlab!20209
parents a0412c79 a8d6f96c
---
title: Epic tree bug fixes
merge_request: 20209
author:
type: fixed
......@@ -15,7 +15,13 @@ export default {
computed: {
removeButtonLabel() {
const { displayReference } = this;
return sprintf(__('Remove %{displayReference}'), { displayReference });
/*
* Giving false as third argument to prevent unescaping of ampersand in
* epic reference. Eg. &42 will remain &42 instead of &42
*
* https://docs.gitlab.com/ee/development/i18n/externalization.html#interpolation
*/
return sprintf(__('Remove %{displayReference}'), { displayReference }, false);
},
stateTitle() {
if (this.isCondensed) return '';
......
......@@ -56,6 +56,7 @@ export default {
return {
isInputFocused: false,
isAutoCompleteOpen: false,
areEventsAssigned: false,
};
},
computed: {
......@@ -74,6 +75,9 @@ export default {
this.$refs.input.focus();
}
},
beforeUpdate() {
this.setupAutoComplete();
},
beforeDestroy() {
const $input = $(this.$refs.input);
$input.off('shown-issues.atwho');
......@@ -116,7 +120,13 @@ export default {
caretPos,
});
},
onBlur() {
onBlur(event) {
// Early exit if this Blur event is caused by card header
const container = this.$root.$el.querySelector('.js-button-container');
if (container && container.contains(event.relatedTarget)) {
return;
}
this.isInputFocused = false;
// Avoid tokenizing partial input when clicking an autocomplete item
......@@ -139,8 +149,11 @@ export default {
this.gfmAutoComplete.setup($input, this.autoCompleteOptions);
}
$input.on('shown-issues.atwho', this.onAutoCompleteToggled.bind(this, true));
$input.on('hidden-issues.atwho', this.onAutoCompleteToggled.bind(this, true));
if (!this.areEventsAssigned) {
$input.on('shown-issues.atwho', this.onAutoCompleteToggled.bind(this, true));
$input.on('hidden-issues.atwho', this.onAutoCompleteToggled.bind(this, true));
}
this.areEventsAssigned = true;
},
onIssuableFormWrapperClick() {
this.$refs.input.focus();
......
......@@ -30,7 +30,7 @@ export default {
},
},
methods: {
...mapActions(['toggleAddItemForm', 'toggleCreateEpicForm']),
...mapActions(['toggleAddItemForm', 'toggleCreateEpicForm', 'setItemInputValue']),
showAddEpicForm() {
this.toggleAddItemForm({
issuableType: issuableTypesMap.EPIC,
......@@ -38,6 +38,7 @@ export default {
});
},
showAddIssueForm() {
this.setItemInputValue('');
this.toggleAddItemForm({
issuableType: issuableTypesMap.ISSUE,
toggleState: true,
......@@ -69,7 +70,7 @@ export default {
</span>
</div>
</div>
<div class="d-inline-flex">
<div class="d-inline-flex js-button-container">
<template v-if="parentItem.userPermissions.adminEpic">
<epic-actions-split-button
:class="headerItems[0].qaClass"
......
......@@ -140,7 +140,8 @@ export default {
},
[types.ADD_PENDING_REFERENCES](state, references) {
state.pendingReferences.push(...references);
const nonDuplicateReferences = references.filter(ref => !state.pendingReferences.includes(ref));
state.pendingReferences.push(...nonDuplicateReferences);
},
[types.REMOVE_PENDING_REFERENCE](state, indexToRemove) {
......
......@@ -123,19 +123,26 @@ describe('RelatedItemsTree', () => {
describe('click event', () => {
let toggleAddItemForm;
let setItemInputValue;
beforeEach(() => {
setItemInputValue = jasmine.createSpy();
toggleAddItemForm = jasmine.createSpy();
wrapper.vm.$store.hotUpdate({
actions: {
setItemInputValue,
toggleAddItemForm,
},
});
});
it('dispatches toggleAddItemForm action', () => {
it('dispatches setItemInputValue and toggleAddItemForm action', () => {
findAddIssuesButton().vm.$emit('click');
expect(setItemInputValue).toHaveBeenCalled();
expect(setItemInputValue.calls.mostRecent().args[1]).toEqual('');
expect(toggleAddItemForm).toHaveBeenCalled();
const payload = toggleAddItemForm.calls.mostRecent().args[1];
......
......@@ -410,6 +410,16 @@ describe('RelatedItemsTree', () => {
expect.arrayContaining(['foo'].concat(reference)),
);
});
it('should not add duplicated `references` param to `pendingReferences` within state', () => {
const references = ['foo', 'bar'];
state.pendingReferences = ['foo'];
mutations[types.ADD_PENDING_REFERENCES](state, references);
expect(state.pendingReferences).toEqual(['foo', 'bar']);
});
});
describe(types.REMOVE_PENDING_REFERENCE, () => {
......
......@@ -218,4 +218,24 @@ describe('IssueToken', () => {
expect(vm.$emit).toHaveBeenCalledWith('pendingIssuableRemoveRequest', vm.idKey);
});
});
describe('tooltip', () => {
beforeEach(() => {
vm = new IssueToken({
propsData: {
idKey,
eventNamespace,
displayReference,
pathIdSeparator,
canRemove: true,
},
}).$mount();
});
it('should not be escaped', () => {
const { originalTitle } = vm.$refs.removeButton.dataset;
expect(originalTitle).toEqual(`Remove ${displayReference}`);
});
});
});
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