Commit 9f5d028e authored by Filipa Lacerda's avatar Filipa Lacerda

Merge branch '34336-related-issues-ui-polish' into 'master'

Related Issues UI Polish

Closes #2756

See merge request !2268
parents e73c1760 10566ddb
...@@ -12,10 +12,6 @@ export default { ...@@ -12,10 +12,6 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
addButtonLabel: {
type: String,
required: true,
},
pendingReferences: { pendingReferences: {
type: Array, type: Array,
required: false, required: false,
...@@ -46,8 +42,12 @@ export default { ...@@ -46,8 +42,12 @@ export default {
}, },
computed: { computed: {
inputPlaceholder() {
return 'Paste issue link or <#issue id>';
},
isSubmitButtonDisabled() { isSubmitButtonDisabled() {
return this.pendingReferences.length === 0 || this.isSubmitting; return (this.inputValue.length === 0 && this.pendingReferences.length === 0)
|| this.isSubmitting;
}, },
}, },
...@@ -84,12 +84,15 @@ export default { ...@@ -84,12 +84,15 @@ export default {
mounted() { mounted() {
const $input = $(this.$refs.input); const $input = $(this.$refs.input);
new GfmAutoComplete(this.autoCompleteSources).setup($input, { new GfmAutoComplete(this.autoCompleteSources).setup($input, {
issues: true, issues: true,
}); });
$input.on('shown-issues.atwho', this.onAutoCompleteToggled.bind(this, true)); $input.on('shown-issues.atwho', this.onAutoCompleteToggled.bind(this, true));
$input.on('hidden-issues.atwho', this.onAutoCompleteToggled.bind(this, false)); $input.on('hidden-issues.atwho', this.onAutoCompleteToggled.bind(this, false));
$input.on('inserted-issues.atwho', this.onInput); $input.on('inserted-issues.atwho', this.onInput);
this.$refs.input.focus();
}, },
beforeDestroy() { beforeDestroy() {
...@@ -126,7 +129,7 @@ export default { ...@@ -126,7 +129,7 @@ export default {
type="text" type="text"
class="js-add-issuable-form-input add-issuable-form-input" class="js-add-issuable-form-input add-issuable-form-input"
:value="inputValue" :value="inputValue"
placeholder="Search issues..." :placeholder="inputPlaceholder"
@input="onInput" @input="onInput"
@focus="onFocus" @focus="onFocus"
@blur="onBlur" /> @blur="onBlur" />
...@@ -140,7 +143,7 @@ export default { ...@@ -140,7 +143,7 @@ export default {
class="js-add-issuable-form-add-button btn btn-new pull-left" class="js-add-issuable-form-add-button btn btn-new pull-left"
@click="onFormSubmit" @click="onFormSubmit"
:disabled="isSubmitButtonDisabled"> :disabled="isSubmitButtonDisabled">
{{ addButtonLabel }} Add
<loadingIcon <loadingIcon
ref="loadingIcon" ref="loadingIcon"
v-if="isSubmitting" v-if="isSubmitting"
......
...@@ -119,11 +119,10 @@ export default { ...@@ -119,11 +119,10 @@ export default {
</component> </component>
<button <button
v-if="canRemove" v-if="canRemove"
v-tooltip
ref="removeButton" ref="removeButton"
type="button" type="button"
class="js-issue-token-remove-button issue-token-remove-button" class="js-issue-token-remove-button issue-token-remove-button"
:title="removeButtonLabel" :aria-label="removeButtonLabel"
@click="onRemoveRequest"> @click="onRemoveRequest">
<i <i
class="fa fa-times" class="fa fa-times"
......
...@@ -76,8 +76,8 @@ export default { ...@@ -76,8 +76,8 @@ export default {
hasBody() { hasBody() {
return this.isFormVisible || this.shouldShowTokenBody; return this.isFormVisible || this.shouldShowTokenBody;
}, },
relatedIssueCount() { badgeLabel() {
return this.relatedIssues.length; return this.isFetching && this.relatedIssues.length === 0 ? '...' : this.relatedIssues.length;
}, },
hasHelpPath() { hasHelpPath() {
return this.helpPath.length > 0; return this.helpPath.length > 0;
...@@ -113,15 +113,13 @@ export default { ...@@ -113,15 +113,13 @@ export default {
<span <span
class="issue-count-badge-count" class="issue-count-badge-count"
:class="{ 'has-btn': this.canAddRelatedIssues }"> :class="{ 'has-btn': this.canAddRelatedIssues }">
{{ relatedIssueCount }} {{ badgeLabel }}
</span> </span>
<button <button
v-if="canAddRelatedIssues" v-if="canAddRelatedIssues"
v-tooltip
ref="issueCountBadgeAddButton" ref="issueCountBadgeAddButton"
type="button" type="button"
class="js-issue-count-badge-add-button issue-count-badge-add-button btn btn-small btn-default" class="js-issue-count-badge-add-button issue-count-badge-add-button btn btn-small btn-default"
title="Add an issue"
aria-label="Add an issue" aria-label="Add an issue"
data-placement="top" data-placement="top"
@click="toggleAddRelatedIssuesForm"> @click="toggleAddRelatedIssuesForm">
...@@ -143,7 +141,6 @@ export default { ...@@ -143,7 +141,6 @@ export default {
:is-submitting="isSubmitting" :is-submitting="isSubmitting"
:input-value="inputValue" :input-value="inputValue"
:pending-references="pendingReferences" :pending-references="pendingReferences"
add-button-label="Add related issues"
:auto-complete-sources="autoCompleteSources" /> :auto-complete-sources="autoCompleteSources" />
</div> </div>
<div <div
......
...@@ -119,7 +119,7 @@ export default { ...@@ -119,7 +119,7 @@ export default {
.catch((res) => { .catch((res) => {
this.isSubmitting = false; this.isSubmitting = false;
// eslint-disable-next-line no-new // eslint-disable-next-line no-new
new Flash(res.data.message || 'An error occurred while submitting related issues.'); new Flash(res.data.message || 'We can\'t find an issue that matches what you are looking for.');
}); });
} }
}, },
......
...@@ -40,31 +40,45 @@ describe('AddIssuableForm', () => { ...@@ -40,31 +40,45 @@ describe('AddIssuableForm', () => {
describe('with data', () => { describe('with data', () => {
describe('without references', () => { describe('without references', () => {
beforeEach(() => { describe('without any input text', () => {
vm = new AddIssuableForm({ beforeEach(() => {
propsData: { vm = new AddIssuableForm({
inputValue: '', propsData: {
addButtonLabel: 'Submit', inputValue: '',
pendingReferences: [], pendingReferences: [],
}, },
}).$mount(); }).$mount();
});
it('should have disabled submit button', () => {
expect(vm.$refs.addButton.disabled).toBe(true);
expect(vm.$refs.loadingIcon).toBeUndefined();
});
}); });
it('should have disabled submit button', () => { describe('with input text', () => {
expect(vm.$refs.addButton.disabled).toBe(true); beforeEach(() => {
expect(vm.$refs.loadingIcon).toBeUndefined(); vm = new AddIssuableForm({
propsData: {
inputValue: 'foo',
pendingReferences: [],
},
}).$mount();
});
it('should not have disabled submit button', () => {
expect(vm.$refs.addButton.disabled).toBe(false);
});
}); });
}); });
describe('with references', () => { describe('with references', () => {
const inputValue = 'foo #123'; const inputValue = 'foo #123';
const addButtonLabel = 'Add issuable';
beforeEach(() => { beforeEach(() => {
vm = new AddIssuableForm({ vm = new AddIssuableForm({
propsData: { propsData: {
inputValue, inputValue,
addButtonLabel,
pendingReferences: [ pendingReferences: [
issuable1.reference, issuable1.reference,
issuable2.reference, issuable2.reference,
...@@ -73,10 +87,6 @@ describe('AddIssuableForm', () => { ...@@ -73,10 +87,6 @@ describe('AddIssuableForm', () => {
}).$mount(); }).$mount();
}); });
it('should put button label in place', () => {
expect(vm.$refs.addButton.textContent.trim()).toEqual(addButtonLabel);
});
it('should put input value in place', () => { it('should put input value in place', () => {
expect(vm.$refs.input.value).toEqual(inputValue); expect(vm.$refs.input.value).toEqual(inputValue);
}); });
...@@ -84,6 +94,10 @@ describe('AddIssuableForm', () => { ...@@ -84,6 +94,10 @@ describe('AddIssuableForm', () => {
it('should render pending issuables items', () => { it('should render pending issuables items', () => {
expect(vm.$el.querySelectorAll('.js-add-issuable-form-token-list-item').length).toEqual(2); expect(vm.$el.querySelectorAll('.js-add-issuable-form-token-list-item').length).toEqual(2);
}); });
it('should not have disabled submit button', () => {
expect(vm.$refs.addButton.disabled).toBe(false);
});
}); });
describe('when submitting', () => { describe('when submitting', () => {
...@@ -91,7 +105,6 @@ describe('AddIssuableForm', () => { ...@@ -91,7 +105,6 @@ describe('AddIssuableForm', () => {
vm = new AddIssuableForm({ vm = new AddIssuableForm({
propsData: { propsData: {
inputValue: '', inputValue: '',
addButtonLabel: 'Submit',
pendingReferences: [ pendingReferences: [
issuable1.reference, issuable1.reference,
issuable2.reference, issuable2.reference,
...@@ -131,7 +144,6 @@ describe('AddIssuableForm', () => { ...@@ -131,7 +144,6 @@ describe('AddIssuableForm', () => {
vm = new AddIssuableForm({ vm = new AddIssuableForm({
propsData: { propsData: {
inputValue: '', inputValue: '',
addButtonLabel: 'Add issuable',
pendingIssuables: [ pendingIssuables: [
issuable1, issuable1,
], ],
......
...@@ -64,6 +64,10 @@ describe('RelatedIssuesBlock', () => { ...@@ -64,6 +64,10 @@ describe('RelatedIssuesBlock', () => {
it('should show loading icon', () => { it('should show loading icon', () => {
expect(vm.$refs.loadingIcon).toBeDefined(); expect(vm.$refs.loadingIcon).toBeDefined();
}); });
it('should show `...` badge count', () => {
expect(vm.badgeLabel).toBe('...');
});
}); });
describe('with canAddRelatedIssues=true', () => { describe('with canAddRelatedIssues=true', () => {
......
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