diff options
author | Dave Pisek <dpisek@gitlab.com> | 2019-09-11 16:20:05 +1000 |
---|---|---|
committer | Dave Pisek <dpisek@gitlab.com> | 2019-09-12 09:59:16 +1000 |
commit | a2b028de000e67e0d20d49f8965053265589a536 (patch) | |
tree | 17151f98cd5df90aee71c3e0cfb232a6219eb536 | |
parent | b966e9e027f467cf3d8228f55d120347f1dd0079 (diff) | |
download | gitlab-ce-project-selector-use-gitlab-ui-search-input.tar.gz |
Use GlSearchBoxByType in project selectorproject-selector-use-gitlab-ui-search-input
Replaces the vanilla input field within the project-selector component
with a `<gl-search-box-by-type>` to improve design consistency.
3 files changed, 40 insertions, 38 deletions
diff --git a/app/assets/javascripts/vue_shared/components/project_selector/project_selector.vue b/app/assets/javascripts/vue_shared/components/project_selector/project_selector.vue index 596fd48f96a..7f0345c7ec0 100644 --- a/app/assets/javascripts/vue_shared/components/project_selector/project_selector.vue +++ b/app/assets/javascripts/vue_shared/components/project_selector/project_selector.vue @@ -1,6 +1,6 @@ <script> import _ from 'underscore'; -import { GlLoadingIcon } from '@gitlab/ui'; +import { GlLoadingIcon, GlSearchBoxByType } from '@gitlab/ui'; import ProjectListItem from './project_list_item.vue'; const SEARCH_INPUT_TIMEOUT_MS = 500; @@ -9,6 +9,7 @@ export default { name: 'ProjectSelector', components: { GlLoadingIcon, + GlSearchBoxByType, ProjectListItem, }, props: { @@ -53,9 +54,6 @@ export default { isSelected(project) { return Boolean(_.findWhere(this.selectedProjects, { id: project.id })); }, - focusSearchInput() { - this.$refs.searchInput.focus(); - }, onInput: _.debounce(function debouncedOnInput() { this.$emit('searched', this.searchQuery); }, SEARCH_INPUT_TIMEOUT_MS), @@ -64,12 +62,11 @@ export default { </script> <template> <div> - <input - ref="searchInput" + <gl-search-box-by-type v-model="searchQuery" :placeholder="__('Search your projects')" type="search" - class="form-control mb-3 js-project-selector-input" + class="mb-3" autofocus @input="onInput" /> diff --git a/changelogs/unreleased/project-selector-use-gitlab-ui-search-input.yml b/changelogs/unreleased/project-selector-use-gitlab-ui-search-input.yml new file mode 100644 index 00000000000..67322de79cd --- /dev/null +++ b/changelogs/unreleased/project-selector-use-gitlab-ui-search-input.yml @@ -0,0 +1,5 @@ +--- +title: Align project selector search box better with design system +merge_request: 32917 +author: +type: changed diff --git a/spec/javascripts/vue_shared/components/project_selector/project_selector_spec.js b/spec/javascripts/vue_shared/components/project_selector/project_selector_spec.js index 7f5f1a778d7..1ca49bd3300 100644 --- a/spec/javascripts/vue_shared/components/project_selector/project_selector_spec.js +++ b/spec/javascripts/vue_shared/components/project_selector/project_selector_spec.js @@ -2,7 +2,9 @@ import Vue from 'vue'; import _ from 'underscore'; import ProjectSelector from '~/vue_shared/components/project_selector/project_selector.vue'; import ProjectListItem from '~/vue_shared/components/project_selector/project_list_item.vue'; -import { shallowMount } from '@vue/test-utils'; + +import { GlSearchBoxByType } from '@gitlab/ui'; +import { mount } from '@vue/test-utils'; import { trimText } from 'spec/helpers/text_helper'; describe('ProjectSelector component', () => { @@ -14,10 +16,12 @@ describe('ProjectSelector component', () => { let selected = []; selected = selected.concat(allProjects.slice(0, 3)).concat(allProjects.slice(5, 8)); + const findSearchInput = () => wrapper.find(GlSearchBoxByType).find('input'); + beforeEach(() => { jasmine.clock().install(); - wrapper = shallowMount(Vue.extend(ProjectSelector), { + wrapper = mount(Vue.extend(ProjectSelector), { propsData: { projectSearchResults: searchResults, selectedProjects: selected, @@ -26,6 +30,7 @@ describe('ProjectSelector component', () => { showLoadingIndicator: false, showSearchErrorMessage: false, }, + sync: false, attachToDocument: true, }); @@ -37,14 +42,15 @@ describe('ProjectSelector component', () => { vm.$destroy(); }); - it('renders the search results', () => { + it(`renders the search results`, () => { expect(wrapper.findAll('.js-project-list-item').length).toBe(5); }); it(`triggers a (debounced) search when the search input value changes`, () => { spyOn(vm, '$emit'); const query = 'my test query!'; - const searchInput = wrapper.find('.js-project-selector-input'); + const searchInput = findSearchInput(); + searchInput.setValue(query); searchInput.trigger('input'); @@ -56,7 +62,7 @@ describe('ProjectSelector component', () => { it(`debounces the search input`, () => { spyOn(vm, '$emit'); - const searchInput = wrapper.find('.js-project-selector-input'); + const searchInput = findSearchInput(); const updateSearchQuery = (count = 0) => { if (count === 10) { @@ -77,9 +83,9 @@ describe('ProjectSelector component', () => { }); it(`includes a placeholder in the search box`, () => { - expect(wrapper.find('.js-project-selector-input').attributes('placeholder')).toBe( - 'Search your projects', - ); + const searchInput = findSearchInput(); + + expect(searchInput.attributes('placeholder')).toBe('Search your projects'); }); it(`triggers a "projectClicked" event when a project is clicked`, () => { @@ -92,41 +98,35 @@ describe('ProjectSelector component', () => { it(`shows a "no results" message if showNoResultsMessage === true`, () => { wrapper.setProps({ showNoResultsMessage: true }); - expect(wrapper.contains('.js-no-results-message')).toBe(true); + return vm.$nextTick().then(() => { + const noResultsEl = wrapper.find('.js-no-results-message'); - const noResultsEl = wrapper.find('.js-no-results-message'); - - expect(trimText(noResultsEl.text())).toEqual('Sorry, no projects matched your search'); + expect(noResultsEl.exists()).toBe(true); + expect(trimText(noResultsEl.text())).toEqual('Sorry, no projects matched your search'); + }); }); it(`shows a "minimum search query" message if showMinimumSearchQueryMessage === true`, () => { wrapper.setProps({ showMinimumSearchQueryMessage: true }); - expect(wrapper.contains('.js-minimum-search-query-message')).toBe(true); - - const minimumSearchEl = wrapper.find('.js-minimum-search-query-message'); + return vm.$nextTick().then(() => { + const minimumSearchEl = wrapper.find('.js-minimum-search-query-message'); - expect(trimText(minimumSearchEl.text())).toEqual('Enter at least three characters to search'); + expect(minimumSearchEl.exists()).toBe(true); + expect(trimText(minimumSearchEl.text())).toEqual('Enter at least three characters to search'); + }); }); it(`shows a error message if showSearchErrorMessage === true`, () => { wrapper.setProps({ showSearchErrorMessage: true }); - expect(wrapper.contains('.js-search-error-message')).toBe(true); - - const errorMessageEl = wrapper.find('.js-search-error-message'); - - expect(trimText(errorMessageEl.text())).toEqual( - 'Something went wrong, unable to search projects', - ); - }); + return vm.$nextTick().then(() => { + const errorMessageEl = wrapper.find('.js-search-error-message'); - it(`focuses the input element when the focusSearchInput() method is called`, () => { - const input = wrapper.find('.js-project-selector-input'); - - expect(document.activeElement).not.toBe(input.element); - vm.focusSearchInput(); - - expect(document.activeElement).toBe(input.element); + expect(errorMessageEl.exists()).toBe(true); + expect(trimText(errorMessageEl.text())).toEqual( + 'Something went wrong, unable to search projects', + ); + }); }); }); |