Adds create option in filtered dropdown

In the filtered search dropdopwn adds a button
to enable creation of missing element.
This commit is contained in:
Filipa Lacerda 2019-01-23 16:27:37 +00:00
parent 8ae38ca2b7
commit 355d8ef72a
2 changed files with 132 additions and 1 deletions

View file

@ -1,15 +1,21 @@
<script>
import $ from 'jquery';
import { GlButton } from '@gitlab/ui';
import { __ } from '~/locale';
import Icon from '~/vue_shared/components/icon.vue';
/**
* Renders a split dropdown with
* an input that allows to search through the given
* array of options.
*
* When there are no results and `showCreateMode` is true
* it renders a create button with the value typed.
*/
export default {
name: 'FilteredSearchDropdown',
components: {
Icon,
GlButton,
},
props: {
title: {
@ -43,6 +49,16 @@ export default {
type: String,
required: true,
},
showCreateMode: {
type: Boolean,
required: false,
default: false,
},
createButtonText: {
type: String,
required: false,
default: __('Create'),
},
},
data() {
return {
@ -64,6 +80,12 @@ export default {
return this.items.slice(0, this.visibleItems);
},
computedCreateButtonText() {
return `${this.createButtonText} ${this.filter}`;
},
shouldRenderCreateButton() {
return this.showCreateMode && this.filteredResults.length === 0 && this.filter !== '';
},
},
mounted() {
/**
@ -112,10 +134,20 @@ export default {
<div class="dropdown-content">
<ul>
<li v-for="(result, i) in filteredResults" :key="i" class="js-filtered-dropdown-result">
<slot name="result" :result="result"> {{ result[filterKey] }} </slot>
<slot name="result" :result="result">{{ result[filterKey] }}</slot>
</li>
</ul>
</div>
<div v-if="shouldRenderCreateButton" class="dropdown-footer">
<slot name="footer" :filter="filter">
<gl-button
class="js-dropdown-create-button btn-transparent"
@click="$emit('createItem', filter)"
>{{ computedCreateButtonText }}</gl-button
>
</slot>
</div>
</div>
</div>
</div>

View file

@ -88,4 +88,103 @@ describe('Filtered search dropdown', () => {
});
});
});
describe('with create mode enabled', () => {
describe('when there are no matches', () => {
beforeEach(() => {
vm = mountComponent(Component, {
items: [
{ title: 'One' },
{ title: 'Two/three' },
{ title: 'Three four' },
{ title: 'Five' },
],
filterKey: 'title',
showCreateMode: true,
});
vm.$el.querySelector('.js-filtered-dropdown-input').value = 'eleven';
vm.$el.querySelector('.js-filtered-dropdown-input').dispatchEvent(new Event('input'));
});
it('renders a create button', done => {
vm.$nextTick(() => {
expect(vm.$el.querySelector('.js-dropdown-create-button')).not.toBeNull();
done();
});
});
it('renders computed button text', done => {
vm.$nextTick(() => {
expect(vm.$el.querySelector('.js-dropdown-create-button').textContent.trim()).toEqual(
'Create eleven',
);
done();
});
});
describe('on click create button', () => {
it('emits createItem event with the filter', done => {
spyOn(vm, '$emit');
vm.$nextTick(() => {
vm.$el.querySelector('.js-dropdown-create-button').click();
expect(vm.$emit).toHaveBeenCalledWith('createItem', 'eleven');
done();
});
});
});
});
describe('when there are matches', () => {
beforeEach(() => {
vm = mountComponent(Component, {
items: [
{ title: 'One' },
{ title: 'Two/three' },
{ title: 'Three four' },
{ title: 'Five' },
],
filterKey: 'title',
showCreateMode: true,
});
vm.$el.querySelector('.js-filtered-dropdown-input').value = 'one';
vm.$el.querySelector('.js-filtered-dropdown-input').dispatchEvent(new Event('input'));
});
it('does not render a create button', done => {
vm.$nextTick(() => {
expect(vm.$el.querySelector('.js-dropdown-create-button')).toBeNull();
done();
});
});
});
});
describe('with create mode disabled', () => {
describe('when there are no matches', () => {
beforeEach(() => {
vm = mountComponent(Component, {
items: [
{ title: 'One' },
{ title: 'Two/three' },
{ title: 'Three four' },
{ title: 'Five' },
],
filterKey: 'title',
});
vm.$el.querySelector('.js-filtered-dropdown-input').value = 'eleven';
vm.$el.querySelector('.js-filtered-dropdown-input').dispatchEvent(new Event('input'));
});
it('does not render a create button', done => {
vm.$nextTick(() => {
expect(vm.$el.querySelector('.js-dropdown-create-button')).toBeNull();
done();
});
});
});
});
});