diff options
11 files changed, 115 insertions, 145 deletions
diff --git a/app/assets/javascripts/boards/components/modal/filters.js b/app/assets/javascripts/boards/components/modal/filters.js index 907556345c6..bf137b27d29 100644 --- a/app/assets/javascripts/boards/components/modal/filters.js +++ b/app/assets/javascripts/boards/components/modal/filters.js @@ -1,17 +1,23 @@ /* global Vue */ import FilteredSearchBoards from '../../filtered_search_boards'; -import { FilteredSearchContainer } from '../../../filtered_search/container'; +import FilteredSearchContainer from '../../../filtered_search/container'; export default { name: 'modal-filters', + props: { + store: { + type: Object, + required: true, + }, + }, mounted() { FilteredSearchContainer.container = this.$el; - this.filteredSearch = new FilteredSearchBoards({path: ''}, false); + this.filteredSearch = new FilteredSearchBoards(this.store, false); }, destroyed() { FilteredSearchContainer.container = document; - gl.issueBoards.ModalStore.setDefaultFilter(); + this.store.path = ''; }, template: '#js-board-modal-filter', }; diff --git a/app/assets/javascripts/boards/components/modal/header.js b/app/assets/javascripts/boards/components/modal/header.js index f4e68f8f93d..23f305ece9c 100644 --- a/app/assets/javascripts/boards/components/modal/header.js +++ b/app/assets/javascripts/boards/components/modal/header.js @@ -1,7 +1,8 @@ /* global Vue */ -require('./tabs'); import modalFilters from './filters'; +require('./tabs'); + (() => { const ModalStore = gl.issueBoards.ModalStore; @@ -66,7 +67,7 @@ import modalFilters from './filters'; <div class="add-issues-search append-bottom-10" v-if="showSearch"> - <modal-filters /> + <modal-filters :store="filter" /> <button type="button" class="btn btn-success btn-inverted prepend-left-10" diff --git a/app/assets/javascripts/boards/components/modal/index.js b/app/assets/javascripts/boards/components/modal/index.js index f290cd13763..3580294b04a 100644 --- a/app/assets/javascripts/boards/components/modal/index.js +++ b/app/assets/javascripts/boards/components/modal/index.js @@ -47,9 +47,6 @@ require('./empty_state'); page() { this.loadIssues(); }, - searchTerm() { - this.searchOperation(); - }, showAddIssuesModal() { if (this.showAddIssuesModal && !this.issues.length) { this.loading = true; @@ -72,17 +69,30 @@ require('./empty_state'); }, }, methods: { - searchOperation: _.debounce(function searchOperationDebounce() { - this.loadIssues(true); - }, 500), loadIssues(clearIssues = false) { if (!this.showAddIssuesModal) return false; - const queryData = Object.assign({}, this.filter, { - search: this.searchTerm, - page: this.page, - per: this.perPage, - }); + const queryData = this.filter.path.split('&').reduce((dataParam, filterParam) => { + if (filterParam === '') return dataParam; + + const data = dataParam; + const paramSplit = filterParam.split('='); + const paramKeyNormalized = paramSplit[0].replace('[]', ''); + const isArray = paramSplit[0].indexOf('[]'); + const value = decodeURIComponent(paramSplit[1]).replace(/\+/g, ' '); + + if (isArray !== -1) { + if (!data[paramKeyNormalized]) { + data[paramKeyNormalized] = []; + } + + data[paramKeyNormalized].push(value); + } else { + data[paramKeyNormalized] = value; + } + + return data; + }, { page: this.page, per: this.perPage }); return gl.boardService.getBacklog(queryData).then((res) => { const data = res.json(); diff --git a/app/assets/javascripts/boards/stores/modal_store.js b/app/assets/javascripts/boards/stores/modal_store.js index 15fc6c79e8d..7ee266a831f 100644 --- a/app/assets/javascripts/boards/stores/modal_store.js +++ b/app/assets/javascripts/boards/stores/modal_store.js @@ -17,17 +17,9 @@ loadingNewPage: false, page: 1, perPage: 50, - }; - - this.setDefaultFilter(); - } - - setDefaultFilter() { - this.store.filter = { - author_id: '', - assignee_id: '', - milestone_title: '', - label_name: [], + filter: { + path: '', + }, }; } diff --git a/app/assets/javascripts/filtered_search/container.js b/app/assets/javascripts/filtered_search/container.js index 02280bd9373..2243c4dd2c5 100644 --- a/app/assets/javascripts/filtered_search/container.js +++ b/app/assets/javascripts/filtered_search/container.js @@ -1,13 +1,14 @@ -let _container = document; +/* eslint-disable class-methods-use-this */ +let container = document; class FilteredSearchContainerClass { - set container(container) { - _container = container; + set container(containerParam) { + container = containerParam; } get container() { - return _container; + return container; } } -export let FilteredSearchContainer = new FilteredSearchContainerClass(); +export default new FilteredSearchContainerClass(); diff --git a/app/assets/javascripts/filtered_search/dropdown_user.js b/app/assets/javascripts/filtered_search/dropdown_user.js index 873bd54001f..04e2afad02f 100644 --- a/app/assets/javascripts/filtered_search/dropdown_user.js +++ b/app/assets/javascripts/filtered_search/dropdown_user.js @@ -56,8 +56,6 @@ require('./filtered_search_dropdown'); } init() { - console.log(this.input); - console.log(this.dropdown); this.droplab.addHook(this.input, this.dropdown, [droplabAjaxFilter], this.config).init(); } } diff --git a/app/assets/javascripts/filtered_search/dropdown_utils.js b/app/assets/javascripts/filtered_search/dropdown_utils.js index efd0b33b95d..59998c2108c 100644 --- a/app/assets/javascripts/filtered_search/dropdown_utils.js +++ b/app/assets/javascripts/filtered_search/dropdown_utils.js @@ -1,4 +1,4 @@ -import { FilteredSearchContainer } from './container'; +import FilteredSearchContainer from './container'; (() => { class DropdownUtils { diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js index 26625459573..5fbe0450bb8 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js @@ -1,5 +1,5 @@ /* global DropLab */ -import { FilteredSearchContainer } from './container'; +import FilteredSearchContainer from './container'; (() => { class FilteredSearchDropdownManager { diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js b/app/assets/javascripts/filtered_search/filtered_search_manager.js index 1d57a0d3abe..7ace51748aa 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_manager.js +++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js @@ -1,4 +1,4 @@ -import { FilteredSearchContainer } from './container'; +import FilteredSearchContainer from './container'; (() => { class FilteredSearchManager { diff --git a/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js b/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js index 5e7f392bbfc..e48d7196c7b 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js +++ b/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js @@ -1,4 +1,4 @@ -import { FilteredSearchContainer } from './container'; +import FilteredSearchContainer from './container'; class FilteredSearchVisualTokens { static getLastVisualTokenBeforeInput() { diff --git a/spec/features/boards/modal_filter_spec.rb b/spec/features/boards/modal_filter_spec.rb index 1cf0d11d448..e26145b6291 100644 --- a/spec/features/boards/modal_filter_spec.rb +++ b/spec/features/boards/modal_filter_spec.rb @@ -1,7 +1,6 @@ require 'rails_helper' describe 'Issue Boards add issue modal filtering', :feature, :js do - include WaitForAjax include WaitForVueResource let(:project) { create(:empty_project, :public) } @@ -23,6 +22,7 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do page.within('.add-issues-modal') do find('.form-control').native.send_keys('testing empty state') + find('.form-control').native.send_keys(:enter) wait_for_vue_resource @@ -33,13 +33,11 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do it 'restores filters when closing' do visit_board - page.within('.add-issues-modal') do - click_button 'Milestone' - - wait_for_ajax - - click_link 'Upcoming' + set_filter('milestone') + click_filter_link('Upcoming') + submit_filter + page.within('.add-issues-modal') do wait_for_vue_resource expect(page).to have_selector('.card', count: 0) @@ -56,37 +54,41 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do end end - context 'author' do - let!(:issue) { create(:issue, project: project, author: user2) } - - before do - project.team << [user2, :developer] + it 'resotres filters after clicking clear button' do + visit_board - visit_board - end + set_filter('milestone') + click_filter_link('Upcoming') + submit_filter - it 'filters by any author' do - page.within('.add-issues-modal') do - click_button 'Author' + page.within('.add-issues-modal') do + wait_for_vue_resource - wait_for_ajax + expect(page).to have_selector('.card', count: 0) - click_link 'Any Author' + find('.clear-search').click - wait_for_vue_resource + wait_for_vue_resource - expect(page).to have_selector('.card', count: 2) - end + expect(page).to have_selector('.card', count: 1) end + end - it 'filters by selected user' do - page.within('.add-issues-modal') do - click_button 'Author' + context 'author' do + let!(:issue) { create(:issue, project: project, author: user2) } + + before do + project.team << [user2, :developer] - wait_for_ajax + visit_board + end - click_link user2.name + it 'filters by selected user' do + set_filter('author') + click_filter_link(user2.name) + submit_filter + page.within('.add-issues-modal') do wait_for_vue_resource expect(page).to have_selector('.card', count: 1) @@ -103,28 +105,12 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do visit_board end - it 'filters by any assignee' do - page.within('.add-issues-modal') do - click_button 'Assignee' - - wait_for_ajax - - click_link 'Any Assignee' - - wait_for_vue_resource - - expect(page).to have_selector('.card', count: 2) - end - end - it 'filters by unassigned' do - page.within('.add-issues-modal') do - click_button 'Assignee' - - wait_for_ajax - - click_link 'Unassigned' + set_filter('assignee') + click_filter_link('No Assignee') + submit_filter + page.within('.add-issues-modal') do wait_for_vue_resource expect(page).to have_selector('.card', count: 1) @@ -132,15 +118,11 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do end it 'filters by selected user' do - page.within('.add-issues-modal') do - click_button 'Assignee' - - wait_for_ajax - - page.within '.dropdown-menu-user' do - click_link user2.name - end + set_filter('assignee') + click_filter_link(user2.name) + submit_filter + page.within('.add-issues-modal') do wait_for_vue_resource expect(page).to have_selector('.card', count: 1) @@ -156,28 +138,12 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do visit_board end - it 'filters by any milestone' do - page.within('.add-issues-modal') do - click_button 'Milestone' - - wait_for_ajax - - click_link 'Any Milestone' - - wait_for_vue_resource - - expect(page).to have_selector('.card', count: 2) - end - end - it 'filters by upcoming milestone' do - page.within('.add-issues-modal') do - click_button 'Milestone' - - wait_for_ajax - - click_link 'Upcoming' + set_filter('milestone') + click_filter_link('Upcoming') + submit_filter + page.within('.add-issues-modal') do wait_for_vue_resource expect(page).to have_selector('.card', count: 0) @@ -185,13 +151,11 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do end it 'filters by selected milestone' do - page.within('.add-issues-modal') do - click_button 'Milestone' - - wait_for_ajax - - click_link milestone.name + set_filter('milestone') + click_filter_link(milestone.name) + submit_filter + page.within('.add-issues-modal') do wait_for_vue_resource expect(page).to have_selector('.card', count: 1) @@ -207,28 +171,12 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do visit_board end - it 'filters by any label' do - page.within('.add-issues-modal') do - click_button 'Label' - - wait_for_ajax - - click_link 'Any Label' - - wait_for_vue_resource - - expect(page).to have_selector('.card', count: 2) - end - end - it 'filters by no label' do - page.within('.add-issues-modal') do - click_button 'Label' - - wait_for_ajax - - click_link 'No Label' + set_filter('label') + click_filter_link('No Label') + submit_filter + page.within('.add-issues-modal') do wait_for_vue_resource expect(page).to have_selector('.card', count: 1) @@ -236,13 +184,11 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do end it 'filters by label' do - page.within('.add-issues-modal') do - click_button 'Label' - - wait_for_ajax - - click_link label.title + set_filter('label') + click_filter_link('No Label') + submit_filter + page.within('.add-issues-modal') do wait_for_vue_resource expect(page).to have_selector('.card', count: 1) @@ -256,4 +202,20 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do click_button('Add issues') end + + def set_filter(type, text = '') + find('.add-issues-modal .filtered-search').native.send_keys("#{type}:#{text}") + end + + def submit_filter + find('.add-issues-modal .filtered-search').native.send_keys(:enter) + end + + def click_filter_link(link_text) + page.within('.add-issues-modal .filtered-search-input-container') do + expect(page).to have_button(link_text) + + click_button(link_text) + end + end end |