summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilipa Lacerda <filipa@gitlab.com>2017-03-14 17:08:33 +0000
committerFilipa Lacerda <filipa@gitlab.com>2017-03-14 17:08:33 +0000
commit0046ffc0248f5edda84f8da0c7aeff97733eae2f (patch)
tree66c1e4a4d0775d7f05a5b2effb199d1767807788
parente52529e25c8f4b597bbf4ae2815f570b4e4a9898 (diff)
parentc7cecae616702a46430ed41e283912ddc22f2612 (diff)
downloadgitlab-ce-0046ffc0248f5edda84f8da0c7aeff97733eae2f.tar.gz
Merge branch 'issue-boards-new-search-bar' into 'master'
Added filtered search bar to issue boards Closes #28312 See merge request !9757
-rw-r--r--app/assets/javascripts/boards/boards_bundle.js20
-rw-r--r--app/assets/javascripts/boards/components/board.js8
-rw-r--r--app/assets/javascripts/boards/components/board_card.js3
-rw-r--r--app/assets/javascripts/boards/components/issue_card_inner.js33
-rw-r--r--app/assets/javascripts/boards/eventhub.js3
-rw-r--r--app/assets/javascripts/boards/filtered_search_boards.js34
-rw-r--r--app/assets/javascripts/boards/models/list.js24
-rw-r--r--app/assets/javascripts/boards/stores/boards_store.js13
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_manager.js21
-rw-r--r--app/assets/javascripts/labels_select.js18
-rw-r--r--app/assets/javascripts/milestone_select.js8
-rw-r--r--app/assets/javascripts/users_select.js5
-rw-r--r--app/assets/stylesheets/framework/filters.scss6
-rw-r--r--app/views/projects/boards/_show.html.haml4
-rw-r--r--app/views/shared/issuable/_filter.html.haml18
-rw-r--r--app/views/shared/issuable/_search_bar.html.haml16
-rw-r--r--changelogs/unreleased/issue-boards-new-search-bar.yml4
-rw-r--r--spec/features/boards/add_issues_modal_spec.rb2
-rw-r--r--spec/features/boards/boards_spec.rb167
-rw-r--r--spec/features/issuables/default_sort_order_spec.rb2
20 files changed, 214 insertions, 195 deletions
diff --git a/app/assets/javascripts/boards/boards_bundle.js b/app/assets/javascripts/boards/boards_bundle.js
index 55d13be6e5f..3874c2819a5 100644
--- a/app/assets/javascripts/boards/boards_bundle.js
+++ b/app/assets/javascripts/boards/boards_bundle.js
@@ -2,6 +2,9 @@
/* global Vue */
/* global BoardService */
+import FilteredSearchBoards from './filtered_search_boards';
+import eventHub from './eventhub';
+
window.Vue = require('vue');
window.Vue.use(require('vue-resource'));
require('./models/issue');
@@ -59,6 +62,14 @@ $(() => {
},
created () {
gl.boardService = new BoardService(this.endpoint, this.bulkUpdatePath, this.boardId);
+
+ this.filterManager = new FilteredSearchBoards(Store.filter, true);
+
+ // Listen for updateTokens event
+ eventHub.$on('updateTokens', this.updateTokens);
+ },
+ beforeDestroy() {
+ eventHub.$off('updateTokens', this.updateTokens);
},
mounted () {
Store.disabled = this.disabled;
@@ -77,11 +88,16 @@ $(() => {
Store.addBlankState();
this.loading = false;
});
- }
+ },
+ methods: {
+ updateTokens() {
+ this.filterManager.updateTokens();
+ }
+ },
});
gl.IssueBoardsSearch = new Vue({
- el: document.getElementById('js-boards-search'),
+ el: document.getElementById('js-add-list'),
data: {
filters: Store.state.filters
},
diff --git a/app/assets/javascripts/boards/components/board.js b/app/assets/javascripts/boards/components/board.js
index 18324de18b3..30d3be453be 100644
--- a/app/assets/javascripts/boards/components/board.js
+++ b/app/assets/javascripts/boards/components/board.js
@@ -28,16 +28,16 @@ require('./board_list');
data () {
return {
detailIssue: Store.detail,
- filters: Store.state.filters,
+ filter: Store.filter,
};
},
watch: {
- filters: {
- handler () {
+ filter: {
+ handler() {
this.list.page = 1;
this.list.getIssues(true);
},
- deep: true
+ deep: true,
},
detailIssue: {
handler () {
diff --git a/app/assets/javascripts/boards/components/board_card.js b/app/assets/javascripts/boards/components/board_card.js
index 795b3cf2ec0..4b72090df31 100644
--- a/app/assets/javascripts/boards/components/board_card.js
+++ b/app/assets/javascripts/boards/components/board_card.js
@@ -17,7 +17,8 @@ export default {
:list="list"
:issue="issue"
:issue-link-base="issueLinkBase"
- :root-path="rootPath" />
+ :root-path="rootPath"
+ :update-filters="true" />
</li>
`,
components: {
diff --git a/app/assets/javascripts/boards/components/issue_card_inner.js b/app/assets/javascripts/boards/components/issue_card_inner.js
index 22a8b971ff8..69e30cec4c5 100644
--- a/app/assets/javascripts/boards/components/issue_card_inner.js
+++ b/app/assets/javascripts/boards/components/issue_card_inner.js
@@ -1,4 +1,6 @@
/* global Vue */
+import eventHub from '../eventhub';
+
(() => {
const Store = gl.issueBoards.BoardsStore;
@@ -23,6 +25,11 @@
type: String,
required: true,
},
+ updateFilters: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
methods: {
showLabel(label) {
@@ -31,29 +38,25 @@
return !this.list.label || label.id !== this.list.label.id;
},
filterByLabel(label, e) {
- let labelToggleText = label.title;
- const labelIndex = Store.state.filters.label_name.indexOf(label.title);
+ if (!this.updateFilters) return;
+
+ const filterPath = gl.issueBoards.BoardsStore.filter.path.split('&');
+ const labelTitle = encodeURIComponent(label.title);
+ const param = `label_name[]=${labelTitle}`;
+ const labelIndex = filterPath.indexOf(param);
$(e.currentTarget).tooltip('hide');
if (labelIndex === -1) {
- Store.state.filters.label_name.push(label.title);
- $('.labels-filter').prepend(`<input type="hidden" name="label_name[]" value="${label.title}" />`);
+ filterPath.push(param);
} else {
- Store.state.filters.label_name.splice(labelIndex, 1);
- labelToggleText = Store.state.filters.label_name[0];
- $(`.labels-filter input[name="label_name[]"][value="${label.title}"]`).remove();
+ filterPath.splice(labelIndex, 1);
}
- const selectedLabels = Store.state.filters.label_name;
- if (selectedLabels.length === 0) {
- labelToggleText = 'Label';
- } else if (selectedLabels.length > 1) {
- labelToggleText = `${selectedLabels[0]} + ${selectedLabels.length - 1} more`;
- }
-
- $('.labels-filter .dropdown-toggle-text').text(labelToggleText);
+ gl.issueBoards.BoardsStore.filter.path = filterPath.join('&');
Store.updateFiltersUrl();
+
+ eventHub.$emit('updateTokens');
},
labelStyle(label) {
return {
diff --git a/app/assets/javascripts/boards/eventhub.js b/app/assets/javascripts/boards/eventhub.js
new file mode 100644
index 00000000000..0948c2e5352
--- /dev/null
+++ b/app/assets/javascripts/boards/eventhub.js
@@ -0,0 +1,3 @@
+import Vue from 'vue';
+
+export default new Vue();
diff --git a/app/assets/javascripts/boards/filtered_search_boards.js b/app/assets/javascripts/boards/filtered_search_boards.js
new file mode 100644
index 00000000000..47448b02bdd
--- /dev/null
+++ b/app/assets/javascripts/boards/filtered_search_boards.js
@@ -0,0 +1,34 @@
+export default class FilteredSearchBoards extends gl.FilteredSearchManager {
+ constructor(store, updateUrl = false) {
+ super('boards');
+
+ this.store = store;
+ this.updateUrl = updateUrl;
+
+ // Issue boards is slightly different, we handle all the requests async
+ // instead or reloading the page, we just re-fire the list ajax requests
+ this.isHandledAsync = true;
+ }
+
+ updateObject(path) {
+ this.store.path = path.substr(1);
+
+ if (this.updateUrl) {
+ gl.issueBoards.BoardsStore.updateFiltersUrl();
+ }
+ }
+
+ updateTokens() {
+ const tokens = document.querySelectorAll('.js-visual-token');
+
+ // Remove all the tokens as they will be replaced by the search manager
+ [].forEach.call(tokens, (el) => {
+ el.parentNode.removeChild(el);
+ });
+
+ this.loadSearchParamsFromURL();
+
+ // Get the placeholder back if search is empty
+ this.filteredSearchInput.dispatchEvent(new Event('input'));
+ }
+}
diff --git a/app/assets/javascripts/boards/models/list.js b/app/assets/javascripts/boards/models/list.js
index f237567208c..3251ca76b26 100644
--- a/app/assets/javascripts/boards/models/list.js
+++ b/app/assets/javascripts/boards/models/list.js
@@ -10,7 +10,6 @@ class List {
this.title = obj.title;
this.type = obj.list_type;
this.preset = ['done', 'blank'].indexOf(this.type) > -1;
- this.filters = gl.issueBoards.BoardsStore.state.filters;
this.page = 1;
this.loading = true;
this.loadingMore = false;
@@ -65,12 +64,27 @@ class List {
}
getIssues (emptyIssues = true) {
- const filters = this.filters;
- const data = { page: this.page };
+ const data = gl.issueBoards.BoardsStore.filter.path.split('&').reduce((data, filterParam) => {
+ if (filterParam === '') return data;
+ 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;
+ }
- Object.keys(filters).forEach((key) => { data[key] = filters[key]; });
+ return data;
+ }, { page: this.page });
- if (this.label) {
+ if (this.label && data.label_name) {
data.label_name = data.label_name.filter(label => label !== this.label.title);
}
diff --git a/app/assets/javascripts/boards/stores/boards_store.js b/app/assets/javascripts/boards/stores/boards_store.js
index 3866c6bbfc6..28ecb322df7 100644
--- a/app/assets/javascripts/boards/stores/boards_store.js
+++ b/app/assets/javascripts/boards/stores/boards_store.js
@@ -8,6 +8,9 @@
gl.issueBoards.BoardsStore = {
disabled: false,
+ filter: {
+ path: '',
+ },
state: {},
detail: {
issue: {}
@@ -18,13 +21,7 @@
},
create () {
this.state.lists = [];
- this.state.filters = {
- author_id: gl.utils.getParameterValues('author_id')[0],
- assignee_id: gl.utils.getParameterValues('assignee_id')[0],
- milestone_title: gl.utils.getParameterValues('milestone_title')[0],
- label_name: gl.utils.getParameterValues('label_name[]'),
- search: ''
- };
+ this.filter.path = gl.utils.getUrlParamsArray().join('&');
},
addList (listObj) {
const list = new List(listObj);
@@ -123,7 +120,7 @@
})[0];
},
updateFiltersUrl () {
- history.pushState(null, null, `?${$.param(this.state.filters)}`);
+ history.pushState(null, null, `?${this.filter.path}`);
}
};
})();
diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js b/app/assets/javascripts/filtered_search/filtered_search_manager.js
index 835e87a28d7..f885932bd91 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_manager.js
+++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js
@@ -106,8 +106,15 @@
e.preventDefault();
if (!activeElements.length) {
- // Prevent droplab from opening dropdown
- this.dropdownManager.destroyDroplab();
+ if (this.isHandledAsync) {
+ e.stopImmediatePropagation();
+
+ this.filteredSearchInput.blur();
+ this.dropdownManager.resetDropdowns();
+ } else {
+ // Prevent droplab from opening dropdown
+ this.dropdownManager.destroyDroplab();
+ }
this.search();
}
@@ -200,6 +207,10 @@
this.handleInputPlaceholder();
this.dropdownManager.resetDropdowns();
+
+ if (this.isHandledAsync) {
+ this.search();
+ }
}
handleInputVisualToken() {
@@ -346,7 +357,11 @@
const parameterizedUrl = `?scope=all&utf8=✓&${paths.join('&')}`;
- gl.utils.visitUrl(parameterizedUrl);
+ if (this.updateObject) {
+ this.updateObject(parameterizedUrl);
+ } else {
+ gl.utils.visitUrl(parameterizedUrl);
+ }
}
getUsernameParams() {
diff --git a/app/assets/javascripts/labels_select.js b/app/assets/javascripts/labels_select.js
index 9e2d14c7f87..c648a0f076c 100644
--- a/app/assets/javascripts/labels_select.js
+++ b/app/assets/javascripts/labels_select.js
@@ -353,31 +353,17 @@
return;
}
- if ($('html').hasClass('issue-boards-page') && !$dropdown.hasClass('js-issue-board-sidebar') &&
- !$dropdown.closest('.add-issues-modal').length) {
- boardsModel = gl.issueBoards.BoardsStore.state.filters;
- } else if ($dropdown.closest('.add-issues-modal').length) {
+ if ($dropdown.closest('.add-issues-modal').length) {
boardsModel = gl.issueBoards.ModalStore.store.filter;
}
if (boardsModel) {
if (label.isAny) {
boardsModel['label_name'] = [];
- }
- else if ($el.hasClass('is-active')) {
+ } else if ($el.hasClass('is-active')) {
boardsModel['label_name'].push(label.title);
}
- else {
- var filters = boardsModel['label_name'];
- filters = filters.filter(function (filteredLabel) {
- return filteredLabel !== label.title;
- });
- boardsModel['label_name'] = filters;
- }
- if (!$dropdown.closest('.add-issues-modal').length) {
- gl.issueBoards.BoardsStore.updateFiltersUrl();
- }
e.preventDefault();
return;
}
diff --git a/app/assets/javascripts/milestone_select.js b/app/assets/javascripts/milestone_select.js
index 51fa5c828b3..4c4f94cb9f3 100644
--- a/app/assets/javascripts/milestone_select.js
+++ b/app/assets/javascripts/milestone_select.js
@@ -124,18 +124,12 @@
return;
}
- if ($('html').hasClass('issue-boards-page') && !$dropdown.hasClass('js-issue-board-sidebar') &&
- !$dropdown.closest('.add-issues-modal').length) {
- boardsStore = gl.issueBoards.BoardsStore.state.filters;
- } else if ($dropdown.closest('.add-issues-modal').length) {
+ if ($dropdown.closest('.add-issues-modal').length) {
boardsStore = gl.issueBoards.ModalStore.store.filter;
}
if (boardsStore) {
boardsStore[$dropdown.data('field-name')] = selected.name;
- if (!$dropdown.closest('.add-issues-modal').length) {
- gl.issueBoards.BoardsStore.updateFiltersUrl();
- }
e.preventDefault();
} else if ($dropdown.hasClass('js-filter-submit') && (isIssueIndex || isMRIndex)) {
if (selected.name != null) {
diff --git a/app/assets/javascripts/users_select.js b/app/assets/javascripts/users_select.js
index 27af859f7d8..c7a57b47834 100644
--- a/app/assets/javascripts/users_select.js
+++ b/app/assets/javascripts/users_select.js
@@ -217,11 +217,6 @@
}
if ($el.closest('.add-issues-modal').length) {
gl.issueBoards.ModalStore.store.filter[$dropdown.data('field-name')] = user.id;
- } else if ($('html').hasClass('issue-boards-page') && !$dropdown.hasClass('js-issue-board-sidebar')) {
- selectedId = user.id;
- gl.issueBoards.BoardsStore.state.filters[$dropdown.data('field-name')] = user.id;
- gl.issueBoards.BoardsStore.updateFiltersUrl();
- e.preventDefault();
} else if ($dropdown.hasClass('js-filter-submit') && (isIssueIndex || isMRIndex)) {
selectedId = user.id;
return Issuable.filterResults($dropdown.closest('form'));
diff --git a/app/assets/stylesheets/framework/filters.scss b/app/assets/stylesheets/framework/filters.scss
index 8f2150066c7..dd2daa4b872 100644
--- a/app/assets/stylesheets/framework/filters.scss
+++ b/app/assets/stylesheets/framework/filters.scss
@@ -156,7 +156,6 @@
width: 100%;
border: 1px solid $border-color;
background-color: $white-light;
- max-width: 87%;
@media (max-width: $screen-xs-min) {
-webkit-flex: 1 1 100%;
@@ -219,6 +218,11 @@
}
}
+.filter-dropdown-container {
+ display: -webkit-flex;
+ display: flex;
+}
+
.dropdown-menu .filter-dropdown-item {
padding: 0;
}
diff --git a/app/views/projects/boards/_show.html.haml b/app/views/projects/boards/_show.html.haml
index 3ae78387938..fa463edd526 100644
--- a/app/views/projects/boards/_show.html.haml
+++ b/app/views/projects/boards/_show.html.haml
@@ -4,6 +4,7 @@
- content_for :page_specific_javascripts do
= page_specific_javascript_bundle_tag('common_vue')
+ = page_specific_javascript_bundle_tag('filtered_search')
= page_specific_javascript_bundle_tag('boards')
= page_specific_javascript_bundle_tag('simulate_drag') if Rails.env.test?
@@ -12,7 +13,8 @@
= render "projects/issues/head"
-= render 'shared/issuable/filter', type: :boards
+.hidden-xs.hidden-sm
+ = render 'shared/issuable/search_bar', type: :boards
#board-app.boards-app{ "v-cloak" => true, data: board_data }
.boards-list{ ":class" => "{ 'is-compact': detailIssueVisible }" }
diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml
index f17ae9f28eb..f0bad69a989 100644
--- a/app/views/shared/issuable/_filter.html.haml
+++ b/app/views/shared/issuable/_filter.html.haml
@@ -1,4 +1,4 @@
-- finder = controller.controller_name == 'issues' || controller.controller_name == 'boards' ? issues_finder : merge_requests_finder
+- finder = controller.controller_name == 'issues' ? issues_finder : merge_requests_finder
- boards_page = controller.controller_name == 'boards'
.issues-filters
@@ -34,21 +34,7 @@
%a{ href: page_filter_path(without: issuable_filter_params) } Reset filters
.pull-right
- - if boards_page
- #js-boards-search.issue-boards-search
- %input.pull-left.form-control{ type: "search", placeholder: "Filter by name...", "v-model" => "filters.search", "debounce" => "250" }
- - if can?(current_user, :admin_list, @project)
- #js-add-issues-btn.pull-right.prepend-left-10
- .dropdown.pull-right
- %button.btn.btn-create.btn-inverted.js-new-board-list{ type: "button", data: { toggle: "dropdown", labels: labels_filter_path, namespace_path: @project.try(:namespace).try(:path), project_path: @project.try(:path) } }
- Add list
- .dropdown-menu.dropdown-menu-paging.dropdown-menu-align-right.dropdown-menu-issues-board-new.dropdown-menu-selectable
- = render partial: "shared/issuable/label_page_default", locals: { show_footer: true, show_create: true, show_boards_content: true, title: "Add list" }
- - if can?(current_user, :admin_label, @project)
- = render partial: "shared/issuable/label_page_create"
- = dropdown_loading
- - else
- = render 'shared/sort_dropdown'
+ = render 'shared/sort_dropdown'
- if @bulk_edit
.issues_bulk_update.hide
diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml
index f8123846596..f1730b1791c 100644
--- a/app/views/shared/issuable/_search_bar.html.haml
+++ b/app/views/shared/issuable/_search_bar.html.haml
@@ -85,8 +85,20 @@
%span.dropdown-label-box{ style: 'background: {{color}}' }
%span.label-title.js-data-value
{{title}}
- .pull-right.filter-dropdown-container
- = render 'shared/sort_dropdown'
+ .filter-dropdown-container
+ - if type == :boards
+ - if can?(current_user, :admin_list, @project)
+ .dropdown.prepend-left-10#js-add-list
+ %button.btn.btn-create.btn-inverted.js-new-board-list{ type: "button", data: { toggle: "dropdown", labels: labels_filter_path, namespace_path: @project.try(:namespace).try(:path), project_path: @project.try(:path) } }
+ Add list
+ .dropdown-menu.dropdown-menu-paging.dropdown-menu-align-right.dropdown-menu-issues-board-new.dropdown-menu-selectable
+ = render partial: "shared/issuable/label_page_default", locals: { show_footer: true, show_create: true, show_boards_content: true, title: "Add list" }
+ - if can?(current_user, :admin_label, @project)
+ = render partial: "shared/issuable/label_page_create"
+ = dropdown_loading
+ #js-add-issues-btn.prepend-left-10
+ - else
+ = render 'shared/sort_dropdown'
- if @bulk_edit
.issues_bulk_update.hide
diff --git a/changelogs/unreleased/issue-boards-new-search-bar.yml b/changelogs/unreleased/issue-boards-new-search-bar.yml
new file mode 100644
index 00000000000..b02be70c470
--- /dev/null
+++ b/changelogs/unreleased/issue-boards-new-search-bar.yml
@@ -0,0 +1,4 @@
+---
+title: Added new filtered search bar to issue boards
+merge_request:
+author:
diff --git a/spec/features/boards/add_issues_modal_spec.rb b/spec/features/boards/add_issues_modal_spec.rb
index a3e24bb5ffa..f7f2d883d2f 100644
--- a/spec/features/boards/add_issues_modal_spec.rb
+++ b/spec/features/boards/add_issues_modal_spec.rb
@@ -51,7 +51,7 @@ describe 'Issue Boards add issue modal', :feature, :js do
end
it 'does not show tooltip on add issues button' do
- button = page.find('.issue-boards-search button', text: 'Add issues')
+ button = page.find('.filter-dropdown-container button', text: 'Add issues')
expect(button[:title]).not_to eq("Please add a list to your board first")
end
diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb
index ecc356f2505..f7e8b78b54d 100644
--- a/spec/features/boards/boards_spec.rb
+++ b/spec/features/boards/boards_spec.rb
@@ -29,7 +29,7 @@ describe 'Issue Boards', feature: true, js: true do
end
it 'shows tooltip on add issues button' do
- button = page.find('.issue-boards-search button', text: 'Add issues')
+ button = page.find('.filter-dropdown-container button', text: 'Add issues')
expect(button[:"data-original-title"]).to eq("Please add a list to your board first")
end
@@ -115,9 +115,8 @@ describe 'Issue Boards', feature: true, js: true do
end
it 'search done list' do
- page.within('#js-boards-search') do
- find('.form-control').set(issue8.title)
- end
+ find('.filtered-search').set(issue8.title)
+ find('.filtered-search').native.send_keys(:enter)
wait_for_vue_resource
@@ -127,9 +126,8 @@ describe 'Issue Boards', feature: true, js: true do
end
it 'search list' do
- page.within('#js-boards-search') do
- find('.form-control').set(issue5.title)
- end
+ find('.filtered-search').set(issue5.title)
+ find('.filtered-search').native.send_keys(:enter)
wait_for_vue_resource
@@ -333,7 +331,7 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_vue_resource
- expect(find('.issue-boards-search')).to have_selector('.open')
+ expect(page).to have_css('#js-add-list.open')
end
it 'creates new list from a new label' do
@@ -359,17 +357,9 @@ describe 'Issue Boards', feature: true, js: true do
context 'filtering' do
it 'filters by author' do
- page.within '.issues-filters' do
- click_button('Author')
- wait_for_ajax
-
- page.within '.dropdown-menu-author' do
- click_link(user2.name)
- end
- wait_for_vue_resource
-
- expect(find('.js-author-search')).to have_content(user2.name)
- end
+ set_filter("author", user2.username)
+ click_filter_link(user2.username)
+ submit_filter
wait_for_vue_resource
wait_for_board_cards(1, 1)
@@ -377,17 +367,9 @@ describe 'Issue Boards', feature: true, js: true do
end
it 'filters by assignee' do
- page.within '.issues-filters' do
- click_button('Assignee')
- wait_for_ajax
-
- page.within '.dropdown-menu-assignee' do
- click_link(user.name)
- end
- wait_for_vue_resource
-
- expect(find('.js-assignee-search')).to have_content(user.name)
- end
+ set_filter("assignee", user.username)
+ click_filter_link(user.username)
+ submit_filter
wait_for_vue_resource
@@ -396,17 +378,9 @@ describe 'Issue Boards', feature: true, js: true do
end
it 'filters by milestone' do
- page.within '.issues-filters' do
- click_button('Milestone')
- wait_for_ajax
-
- page.within '.milestone-filter' do
- click_link(milestone.title)
- end
- wait_for_vue_resource
-
- expect(find('.js-milestone-select')).to have_content(milestone.title)
- end
+ set_filter("milestone", "\"#{milestone.title}\"")
+ click_filter_link(milestone.title)
+ submit_filter
wait_for_vue_resource
wait_for_board_cards(1, 1)
@@ -415,16 +389,9 @@ describe 'Issue Boards', feature: true, js: true do
end
it 'filters by label' do
- page.within '.issues-filters' do
- click_button('Label')
- wait_for_ajax
-
- page.within '.dropdown-menu-labels' do
- click_link(testing.title)
- wait_for_vue_resource
- find('.dropdown-menu-close').click
- end
- end
+ set_filter("label", testing.title)
+ click_filter_link(testing.title)
+ submit_filter
wait_for_vue_resource
wait_for_board_cards(1, 1)
@@ -432,19 +399,14 @@ describe 'Issue Boards', feature: true, js: true do
end
it 'filters by label with space after reload' do
- page.within '.issues-filters' do
- click_button('Label')
- wait_for_ajax
-
- page.within '.dropdown-menu-labels' do
- click_link(accepting.title)
- wait_for_vue_resource(spinner: false)
- find('.dropdown-menu-close').click
- end
- end
+ set_filter("label", "\"#{accepting.title}\"")
+ click_filter_link(accepting.title)
+ submit_filter
# Test after reload
page.evaluate_script 'window.location.reload()'
+ wait_for_board_cards(1, 1)
+ wait_for_empty_boards((2..3))
wait_for_vue_resource
@@ -460,26 +422,16 @@ describe 'Issue Boards', feature: true, js: true do
end
it 'removes filtered labels' do
- wait_for_vue_resource
+ set_filter("label", testing.title)
+ click_filter_link(testing.title)
+ submit_filter
- page.within '.labels-filter' do
- click_button('Label')
- wait_for_ajax
-
- page.within '.dropdown-menu-labels' do
- click_link(testing.title)
- wait_for_vue_resource(spinner: false)
- end
-
- expect(page).to have_css('input[name="label_name[]"]', visible: false)
+ wait_for_board_cards(1, 1)
- page.within '.dropdown-menu-labels' do
- click_link(testing.title)
- wait_for_vue_resource(spinner: false)
- end
+ find('.clear-search').click
+ submit_filter
- expect(page).not_to have_css('input[name="label_name[]"]', visible: false)
- end
+ wait_for_board_cards(1, 8)
end
it 'infinite scrolls list with label filter' do
@@ -487,16 +439,9 @@ describe 'Issue Boards', feature: true, js: true do
create(:labeled_issue, project: project, labels: [planning, testing])
end
- page.within '.issues-filters' do
- click_button('Label')
- wait_for_ajax
-
- page.within '.dropdown-menu-labels' do
- click_link(testing.title)
- wait_for_vue_resource
- find('.dropdown-menu-close').click
- end
- end
+ set_filter("label", testing.title)
+ click_filter_link(testing.title)
+ submit_filter
wait_for_vue_resource
@@ -518,18 +463,13 @@ describe 'Issue Boards', feature: true, js: true do
end
it 'filters by multiple labels' do
- page.within '.issues-filters' do
- click_button('Label')
- wait_for_ajax
+ set_filter("label", testing.title)
+ click_filter_link(testing.title)
- page.within(find('.dropdown-menu-labels')) do
- click_link(testing.title)
- wait_for_vue_resource
- click_link(bug.title)
- wait_for_vue_resource
- find('.dropdown-menu-close').click
- end
- end
+ set_filter("label", bug.title)
+ click_filter_link(bug.title)
+
+ submit_filter
wait_for_vue_resource
@@ -545,14 +485,14 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_vue_resource
end
+ page.within('.tokens-container') do
+ expect(page).to have_content(bug.title)
+ end
+
wait_for_vue_resource
wait_for_board_cards(1, 1)
wait_for_empty_boards((2..3))
-
- page.within('.labels-filter') do
- expect(find('.dropdown-toggle-text')).to have_content(bug.title)
- end
end
it 'removes label filter by clicking label button on issue' do
@@ -560,16 +500,13 @@ describe 'Issue Boards', feature: true, js: true do
page.within(find('.card', match: :first)) do
click_button(bug.title)
end
+
wait_for_vue_resource
expect(page).to have_selector('.card', count: 1)
end
wait_for_vue_resource
-
- page.within('.labels-filter') do
- expect(find('.dropdown-toggle-text')).to have_content(bug.title)
- end
end
end
end
@@ -643,4 +580,20 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_board_cards(board, 0)
end
end
+
+ def set_filter(type, text)
+ find('.filtered-search').native.send_keys("#{type}:#{text}")
+ end
+
+ def submit_filter
+ find('.filtered-search').native.send_keys(:enter)
+ end
+
+ def click_filter_link(link_text)
+ page.within('.filtered-search-input-container') do
+ expect(page).to have_button(link_text)
+
+ click_button(link_text)
+ end
+ end
end
diff --git a/spec/features/issuables/default_sort_order_spec.rb b/spec/features/issuables/default_sort_order_spec.rb
index 73553f97d6f..bfe43bff10f 100644
--- a/spec/features/issuables/default_sort_order_spec.rb
+++ b/spec/features/issuables/default_sort_order_spec.rb
@@ -176,7 +176,7 @@ describe 'Projects > Issuables > Default sort order', feature: true do
end
def selected_sort_order
- find('.pull-right .dropdown button').text.downcase
+ find('.filter-dropdown-container .dropdown button').text.downcase
end
def visit_merge_requests_with_state(project, state)