Commit e7f13df7 authored by Fatih Acet's avatar Fatih Acet Committed by Ruben Davila

Merge branch 'issue-boards-search' into 'master'

Added search for all lists on issue boards

Adds a search box to allow the user to search all lists in issue boards rather than just the backlog.

![Screen_Shot_2016-08-30_at_10.33.15](/uploads/67e96055d60a9b3209ce3831a1980c09/Screen_Shot_2016-08-30_at_10.33.15.png)

![Screen_Shot_2016-08-30_at_10.33.19](/uploads/8d5253b8f2ecf1cf9a69d70be8ccf1f9/Screen_Shot_2016-08-30_at_10.33.19.png)

Closes #21139

See merge request !6101
Conflicts:
	app/assets/stylesheets/pages/boards.scss
	app/views/projects/boards/components/_board.html.haml
parent fb9d3e6e
...@@ -15,6 +15,53 @@ v 8.11.4 ...@@ -15,6 +15,53 @@ v 8.11.4
- Fix pipelines tab layout regression. !5952 - Fix pipelines tab layout regression. !5952
- Fix "Wiki" link not appearing in navigation for projects with external wiki. !6057 - Fix "Wiki" link not appearing in navigation for projects with external wiki. !6057
- Do not enforce using hash with hidden key in CI configuration. !6079 - Do not enforce using hash with hidden key in CI configuration. !6079
v 8.12.0 (unreleased)
- Make push events have equal vertical spacing.
- Add two-factor recovery endpoint to internal API !5510
- Remove vendor prefixes for linear-gradient CSS (ClemMakesApps)
- Add font color contrast to external label in admin area (ClemMakesApps)
- Change logo animation to CSS (ClemMakesApps)
- Change merge_error column from string to text type
- Reduce contributions calendar data payload (ClemMakesApps)
- Add `web_url` field to issue, merge request, and snippet API objects (Ben Boeckel)
- Set path for all JavaScript cookies to honor GitLab's subdirectory setting !5627 (Mike Greiling)
- Shorten task status phrase (ClemMakesApps)
- Add hover color to emoji icon (ClemMakesApps)
- Fix branches page dropdown sort alignment (ClemMakesApps)
- Add white background for no readme container (ClemMakesApps)
- Optimistic locking for Issues and Merge Requests (title and description overriding prevention)
- Add `wiki_page_events` to project hook APIs (Ben Boeckel)
- Remove Gitorious import
- Fix inconsistent background color for filter input field (ClemMakesApps)
- Add Sentry logging to API calls
- Automatically expand hidden discussions when accessed by a permalink !5585 (Mike Greiling)
- Remove unused mixins (ClemMakesApps)
- Add search to all issue board lists
- Fix groups sort dropdown alignment (ClemMakesApps)
- Add horizontal scrolling to all sub-navs on mobile viewports (ClemMakesApps)
- Fix markdown help references (ClemMakesApps)
- Add last commit time to repo view (ClemMakesApps)
- Added project specific enable/disable setting for LFS !5997
- Added tests for diff notes
- Add a button to download latest successful artifacts for branches and tags !5142
- Add delimiter to project stars and forks count (ClemMakesApps)
- Fix badge count alignment (ClemMakesApps)
- Fix branch title trailing space on hover (ClemMakesApps)
- Award emoji tooltips containing more than 10 usernames are now truncated !4780 (jlogandavison)
- Fix duplicate "me" in award emoji tooltip !5218 (jlogandavison)
- Fix spacing and vertical alignment on build status icon on commits page (ClemMakesApps)
- Update merge_requests.md with a simpler way to check out a merge request. !5944
- Fix button missing type (ClemMakesApps)
- Move to project dropdown with infinite scroll for better performance
- Fix leaking of submit buttons outside the width of a main container !18731 (originally by @pavelloz)
- Load branches asynchronously in Cherry Pick and Revert dialogs.
- Add merge request versions !5467
- Change using size to use count and caching it for number of group members. !5935
- Added 'only_allow_merge_if_build_succeeds' project setting in the API. !5930 (Duck)
- Reduce number of database queries on builds tab
- Capitalize mentioned issue timeline notes (ClemMakesApps)
- Use the default branch for displaying the project icon instead of master !5792 (Hannes Rosenögger)
- Adds response mime type to transaction metric action when it's not HTML
- Fix hover leading space bug in pipeline graph !5980 - Fix hover leading space bug in pipeline graph !5980
- Fix sorting issues by "last updated" doesn't work after import from GitHub - Fix sorting issues by "last updated" doesn't work after import from GitHub
- GitHub importer use default project visibility for non-private projects - GitHub importer use default project visibility for non-private projects
......
...@@ -54,4 +54,11 @@ $(() => { ...@@ -54,4 +54,11 @@ $(() => {
}); });
} }
}); });
gl.IssueBoardsSearch = new Vue({
el: '#js-boards-seach',
data: {
filters: Store.state.filters
}
});
}); });
...@@ -21,15 +21,10 @@ ...@@ -21,15 +21,10 @@
}, },
data () { data () {
return { return {
query: '',
filters: Store.state.filters filters: Store.state.filters
}; };
}, },
watch: { watch: {
query () {
this.list.filters = this.getFilterData();
this.list.getIssues(true);
},
filters: { filters: {
handler () { handler () {
this.list.page = 1; this.list.page = 1;
...@@ -38,16 +33,6 @@ ...@@ -38,16 +33,6 @@
deep: true deep: true
} }
}, },
methods: {
getFilterData () {
const filters = this.filters;
let queryData = { search: this.query };
Object.keys(filters).forEach((key) => { queryData[key] = filters[key]; });
return queryData;
}
},
ready () { ready () {
const options = gl.issueBoards.getBoardSortableDefaultOptions({ const options = gl.issueBoards.getBoardSortableDefaultOptions({
disabled: this.disabled, disabled: this.disabled,
......
...@@ -59,10 +59,6 @@ class List { ...@@ -59,10 +59,6 @@ class List {
} }
} }
canSearch () {
return this.type === 'backlog';
}
getIssues (emptyIssues = true) { getIssues (emptyIssues = true) {
const filters = this.filters; const filters = this.filters;
let data = { page: this.page }; let data = { page: this.page };
......
...@@ -15,7 +15,8 @@ ...@@ -15,7 +15,8 @@
author_id: gl.utils.getParameterValues('author_id')[0], author_id: gl.utils.getParameterValues('author_id')[0],
assignee_id: gl.utils.getParameterValues('assignee_id')[0], assignee_id: gl.utils.getParameterValues('assignee_id')[0],
milestone_title: gl.utils.getParameterValues('milestone_title')[0], milestone_title: gl.utils.getParameterValues('milestone_title')[0],
label_name: gl.utils.getParameterValues('label_name[]') label_name: gl.utils.getParameterValues('label_name[]'),
search: ''
}; };
}, },
addList (listObj) { addList (listObj) {
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
.is-dragging { .is-dragging {
// Important because plugin sets inline CSS // Important because plugin sets inline CSS
opacity: 1!important; opacity: 1!important;
* { * {
// !important to make sure no style can override this when dragging // !important to make sure no style can override this when dragging
cursor: -webkit-grabbing!important; cursor: -webkit-grabbing!important;
...@@ -155,40 +155,6 @@ ...@@ -155,40 +155,6 @@
border-bottom: 1px solid $border-color; border-bottom: 1px solid $border-color;
} }
.board-search-container {
position: relative;
background-color: #fff;
.form-control {
padding-right: 30px;
}
}
.board-search-icon,
.board-search-clear-btn {
position: absolute;
right: $gl-padding + 10px;
top: 50%;
margin-top: -7px;
font-size: 14px;
}
.board-search-icon {
color: $gl-placeholder-color;
}
.board-search-clear-btn {
padding: 0;
line-height: 1;
background: transparent;
border: 0;
outline: 0;
&:hover {
color: $gl-link-color;
}
}
.board-delete { .board-delete {
margin-right: 10px; margin-right: 10px;
padding: 0; padding: 0;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
"v-if" => "!list.preset && list.id" } "v-if" => "!list.preset && list.id" }
%button.board-delete.has-tooltip.pull-right{ type: "button", title: "Delete list", "aria-label" => "Delete list", data: { placement: "bottom" }, "@click.stop" => "deleteBoard" } %button.board-delete.has-tooltip.pull-right{ type: "button", title: "Delete list", "aria-label" => "Delete list", data: { placement: "bottom" }, "@click.stop" => "deleteBoard" }
= icon("trash") = icon("trash")
= icon("spinner spin", class: "board-header-loading-spinner pull-right", "v-show" => "list.loadingMore")
%board-list{ "inline-template" => true, %board-list{ "inline-template" => true,
"v-if" => "list.type !== 'blank'", "v-if" => "list.type !== 'blank'",
":list" => "list", ":list" => "list",
......
...@@ -27,15 +27,18 @@ ...@@ -27,15 +27,18 @@
= render "shared/issuable/label_dropdown" = render "shared/issuable/label_dropdown"
.pull-right .pull-right
- if controller.controller_name == 'boards' && can?(current_user, :admin_list, @project) - if controller.controller_name == 'boards'
.dropdown #js-boards-seach.issue-boards-search
%button.btn.btn-create.js-new-board-list{ type: "button", data: { toggle: "dropdown", labels: labels_filter_path, project_id: @project.try(:id) } } %input.pull-left.form-control{ type: "search", placeholder: "Filter by name...", "v-model" => "filters.search", "debounce" => "250" }
Create new list - if can?(current_user, :admin_list, @project)
.dropdown-menu.dropdown-menu-paging.dropdown-menu-align-right.dropdown-menu-issues-board-new.dropdown-menu-selectable .dropdown.pull-right
= render partial: "shared/issuable/label_page_default", locals: { show_footer: true, show_create: true, show_boards_content: true, title: "Create a new list" } %button.btn.btn-create.js-new-board-list{ type: "button", data: { toggle: "dropdown", labels: labels_filter_path, project_id: @project.try(:id) } }
- if can?(current_user, :admin_label, @project) Create new list
= render partial: "shared/issuable/label_page_create" .dropdown-menu.dropdown-menu-paging.dropdown-menu-align-right.dropdown-menu-issues-board-new.dropdown-menu-selectable
= dropdown_loading = render partial: "shared/issuable/label_page_default", locals: { show_footer: true, show_create: true, show_boards_content: true, title: "Create a new list" }
- if can?(current_user, :admin_label, @project)
= render partial: "shared/issuable/label_page_create"
= dropdown_loading
- else - else
= render 'shared/sort_dropdown' = render 'shared/sort_dropdown'
......
...@@ -110,6 +110,45 @@ describe 'Issue Boards', feature: true, js: true do ...@@ -110,6 +110,45 @@ describe 'Issue Boards', feature: true, js: true do
end end
end end
it 'search backlog list' do
page.within('#js-boards-seach') do
find('.form-control').set(issue1.title)
end
wait_for_vue_resource
expect(find('.board:nth-child(1)')).to have_selector('.card', count: 1)
expect(find('.board:nth-child(2)')).to have_selector('.card', count: 0)
expect(find('.board:nth-child(3)')).to have_selector('.card', count: 0)
expect(find('.board:nth-child(4)')).to have_selector('.card', count: 0)
end
it 'search done list' do
page.within('#js-boards-seach') do
find('.form-control').set(issue8.title)
end
wait_for_vue_resource
expect(find('.board:nth-child(1)')).to have_selector('.card', count: 0)
expect(find('.board:nth-child(2)')).to have_selector('.card', count: 0)
expect(find('.board:nth-child(3)')).to have_selector('.card', count: 0)
expect(find('.board:nth-child(4)')).to have_selector('.card', count: 1)
end
it 'search list' do
page.within('#js-boards-seach') do
find('.form-control').set(issue5.title)
end
wait_for_vue_resource
expect(find('.board:nth-child(1)')).to have_selector('.card', count: 0)
expect(find('.board:nth-child(2)')).to have_selector('.card', count: 1)
expect(find('.board:nth-child(3)')).to have_selector('.card', count: 0)
expect(find('.board:nth-child(4)')).to have_selector('.card', count: 0)
end
it 'allows user to delete board' do it 'allows user to delete board' do
page.within(find('.board:nth-child(2)')) do page.within(find('.board:nth-child(2)')) do
find('.board-delete').click find('.board-delete').click
...@@ -169,32 +208,6 @@ describe 'Issue Boards', feature: true, js: true do ...@@ -169,32 +208,6 @@ describe 'Issue Boards', feature: true, js: true do
end end
end end
it 'is searchable' do
page.within(find('.board', match: :first)) do
find('.form-control').set issue1.title
wait_for_vue_resource(spinner: false)
expect(page).to have_selector('.card', count: 1)
end
end
it 'clears search' do
page.within(find('.board', match: :first)) do
find('.form-control').set issue1.title
expect(page).to have_selector('.card', count: 1)
find('.board-search-clear-btn').click
end
wait_for_vue_resource
page.within(find('.board', match: :first)) do
expect(page).to have_selector('.card', count: 6)
end
end
it 'moves issue from backlog into list' do it 'moves issue from backlog into list' do
drag_to(list_to_index: 1) drag_to(list_to_index: 1)
......
...@@ -60,15 +60,6 @@ describe('List model', () => { ...@@ -60,15 +60,6 @@ describe('List model', () => {
}, 0); }, 0);
}); });
it('can\'t search when not backlog', () => {
expect(list.canSearch()).toBe(false);
});
it('can search when backlog', () => {
list.type = 'backlog';
expect(list.canSearch()).toBe(true);
});
it('gets issue from list', (done) => { it('gets issue from list', (done) => {
setTimeout(() => { setTimeout(() => {
const issue = list.findIssue(1); const issue = list.findIssue(1);
......
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