Commit bf91fb92 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'author-filter' into 'master'

Author filter for issues and merge requests pages

This is first step in implementing #1604

See merge request !1309
parents eb12e3ab c8a96d8a
...@@ -29,4 +29,31 @@ class Projects::ApplicationController < ApplicationController ...@@ -29,4 +29,31 @@ class Projects::ApplicationController < ApplicationController
redirect_to project_tree_path(@project, @ref), notice: "This action is not allowed unless you are on top of a branch" redirect_to project_tree_path(@project, @ref), notice: "This action is not allowed unless you are on top of a branch"
end end
end end
def set_filter_variables(collection)
params[:sort] ||= 'newest'
params[:scope] = 'all' if params[:scope].blank?
params[:state] = 'opened' if params[:state].blank?
@sort = params[:sort].humanize
assignee_id = params[:assignee_id]
author_id = params[:author_id]
milestone_id = params[:milestone_id]
if assignee_id.present? && !assignee_id.to_i.zero?
@assignee = @project.team.find(assignee_id)
end
if author_id.present? && !author_id.to_i.zero?
@author = @project.team.find(assignee_id)
end
if milestone_id.present? && !milestone_id.to_i.zero?
@milestone = @project.milestones.find(milestone_id)
end
@assignees = User.where(id: collection.pluck(:assignee_id))
@authors = User.where(id: collection.pluck(:author_id))
end
end end
...@@ -18,18 +18,12 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -18,18 +18,12 @@ class Projects::IssuesController < Projects::ApplicationController
def index def index
terms = params['issue_search'] terms = params['issue_search']
set_filter_variables(@project.issues)
@issues = issues_filtered @issues = IssuesFinder.new.execute(current_user, params.merge(project_id: @project.id))
@issues = @issues.full_search(terms) if terms.present? @issues = @issues.full_search(terms) if terms.present?
@issues = @issues.page(params[:page]).per(20) @issues = @issues.page(params[:page]).per(20)
assignee_id, milestone_id = params[:assignee_id], params[:milestone_id]
@assignee = @project.team.find(assignee_id) if assignee_id.present? && !assignee_id.to_i.zero?
@milestone = @project.milestones.find(milestone_id) if milestone_id.present? && !milestone_id.to_i.zero?
sort_param = params[:sort] || 'newest'
@sort = sort_param.humanize unless sort_param.empty?
@assignees = User.where(id: @project.issues.pluck(:assignee_id)).active
respond_to do |format| respond_to do |format|
format.html format.html
format.atom { render layout: false } format.atom { render layout: false }
...@@ -127,12 +121,6 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -127,12 +121,6 @@ class Projects::IssuesController < Projects::ApplicationController
return render_404 unless @project.issues_enabled return render_404 unless @project.issues_enabled
end end
def issues_filtered
params[:scope] = 'all' if params[:scope].blank?
params[:state] = 'opened' if params[:state].blank?
@issues = IssuesFinder.new.execute(current_user, params.merge(project_id: @project.id))
end
# Since iids are implemented only in 6.1 # Since iids are implemented only in 6.1
# user may navigate to issue page using old global ids. # user may navigate to issue page using old global ids.
# #
......
...@@ -17,18 +17,10 @@ class Projects::MergeRequestsController < Projects::ApplicationController ...@@ -17,18 +17,10 @@ class Projects::MergeRequestsController < Projects::ApplicationController
before_filter :authorize_modify_merge_request!, only: [:close, :edit, :update, :sort] before_filter :authorize_modify_merge_request!, only: [:close, :edit, :update, :sort]
def index def index
params[:sort] ||= 'newest' set_filter_variables(@project.merge_requests)
params[:scope] = 'all' if params[:scope].blank?
params[:state] = 'opened' if params[:state].blank?
@merge_requests = MergeRequestsFinder.new.execute(current_user, params.merge(project_id: @project.id)) @merge_requests = MergeRequestsFinder.new.execute(current_user, params.merge(project_id: @project.id))
@merge_requests = @merge_requests.page(params[:page]).per(20) @merge_requests = @merge_requests.page(params[:page]).per(20)
@sort = params[:sort].humanize
assignee_id, milestone_id = params[:assignee_id], params[:milestone_id]
@assignee = @project.team.find(assignee_id) if assignee_id.present? && !assignee_id.to_i.zero?
@milestone = @project.milestones.find(milestone_id) if milestone_id.present? && !milestone_id.to_i.zero?
@assignees = User.where(id: @project.merge_requests.pluck(:assignee_id))
end end
def show def show
......
...@@ -33,6 +33,7 @@ class IssuableFinder ...@@ -33,6 +33,7 @@ class IssuableFinder
items = by_search(items) items = by_search(items)
items = by_milestone(items) items = by_milestone(items)
items = by_assignee(items) items = by_assignee(items)
items = by_author(items)
items = by_label(items) items = by_label(items)
items = sort(items) items = sort(items)
end end
...@@ -125,6 +126,14 @@ class IssuableFinder ...@@ -125,6 +126,14 @@ class IssuableFinder
items items
end end
def by_author(items)
if params[:author_id].present?
items = items.where(author_id: (params[:author_id] == '0' ? nil : params[:author_id]))
end
items
end
def by_label(items) def by_label(items)
if params[:label_name].present? if params[:label_name].present?
label_names = params[:label_name].split(",") label_names = params[:label_name].split(",")
......
.issues-filters
.dropdown.inline
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%i.fa.fa-user
%span.light assignee:
- if @assignee.present?
%strong= @assignee.name
- elsif params[:assignee_id] == "0"
Unassigned
- else
Any
%b.caret
%ul.dropdown-menu
%li
= link_to project_filter_path(assignee_id: nil) do
Any
= link_to project_filter_path(assignee_id: 0) do
Unassigned
- @assignees.sort_by(&:name).each do |user|
%li
= link_to project_filter_path(assignee_id: user.id) do
= image_tag avatar_icon(user.email), class: "avatar s16", alt: ''
= user.name
.dropdown.inline.prepend-left-10
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%i.fa.fa-user
%span.light author:
- if @author.present?
%strong= @author.name
- elsif params[:author_id] == "0"
Unassigned
- else
Any
%b.caret
%ul.dropdown-menu
%li
= link_to project_filter_path(author_id: nil) do
Any
= link_to project_filter_path(author_id: 0) do
Unassigned
- @authors.sort_by(&:name).each do |user|
%li
= link_to project_filter_path(author_id: user.id) do
= image_tag avatar_icon(user.email), class: "avatar s16", alt: ''
= user.name
.dropdown.inline.prepend-left-10
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%i.fa.fa-clock-o
%span.light milestone:
- if @milestone.present?
%strong= @milestone.title
- elsif params[:milestone_id] == "0"
None (backlog)
- else
Any
%b.caret
%ul.dropdown-menu
%li
= link_to project_filter_path(milestone_id: nil) do
Any
= link_to project_filter_path(milestone_id: 0) do
None (backlog)
- project_active_milestones.each do |milestone|
%li
= link_to project_filter_path(milestone_id: milestone.id) do
%strong= milestone.title
%small.light= milestone.expires_at
.pull-right
= render 'shared/sort_dropdown'
.append-bottom-10 .append-bottom-10
.check-all-holder .check-all-holder
= check_box_tag "check_all_issues", nil, false, class: "check_all_issues left" = check_box_tag "check_all_issues", nil, false, class: "check_all_issues left"
.issues-filters = render 'projects/issuable_filter'
.dropdown.inline
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%i.fa.fa-user
%span.light assignee:
- if @assignee.present?
%strong= @assignee.name
- elsif params[:assignee_id] == "0"
Unassigned
- else
Any
%b.caret
%ul.dropdown-menu
%li
= link_to project_filter_path(assignee_id: nil) do
Any
= link_to project_filter_path(assignee_id: 0) do
Unassigned
- @assignees.sort_by(&:name).each do |user|
%li
= link_to project_filter_path(assignee_id: user.id) do
= image_tag avatar_icon(user.email), class: "avatar s16", alt: ''
= user.name
.dropdown.inline.prepend-left-10
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%i.fa.fa-clock-o
%span.light milestone:
- if @milestone.present?
%strong= @milestone.title
- elsif params[:milestone_id] == "0"
None (backlog)
- else
Any
%b.caret
%ul.dropdown-menu
%li
= link_to project_filter_path(milestone_id: nil) do
Any
= link_to project_filter_path(milestone_id: 0) do
None (backlog)
- project_active_milestones.each do |milestone|
%li
= link_to project_filter_path(milestone_id: milestone.id) do
%strong= milestone.title
%small.light= milestone.expires_at
.pull-right
= render 'shared/sort_dropdown'
.clearfix .clearfix
.issues_bulk_update.hide .issues_bulk_update.hide
......
...@@ -5,56 +5,8 @@ ...@@ -5,56 +5,8 @@
= render 'shared/project_filter', project_entities_path: project_merge_requests_path(@project), = render 'shared/project_filter', project_entities_path: project_merge_requests_path(@project),
labels: true, redirect: 'merge_requests', entity: 'merge_request' labels: true, redirect: 'merge_requests', entity: 'merge_request'
.col-md-9 .col-md-9
.mr-filters.append-bottom-10 .append-bottom-10
.dropdown.inline = render 'projects/issuable_filter'
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%i.fa.fa-user
%span.light assignee:
- if @assignee.present?
%strong= @assignee.name
- elsif params[:assignee_id] == "0"
Unassigned
- else
Any
%b.caret
%ul.dropdown-menu
%li
= link_to project_filter_path(assignee_id: nil) do
Any
= link_to project_filter_path(assignee_id: 0) do
Unassigned
- @assignees.sort_by(&:name).each do |user|
%li
= link_to project_filter_path(assignee_id: user.id) do
= image_tag avatar_icon(user.email), class: "avatar s16", alt: ''
= user.name
.dropdown.inline.prepend-left-10
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%i.fa.fa-clock-o
%span.light milestone:
- if @milestone.present?
%strong= @milestone.title
- elsif params[:milestone_id] == "0"
None (backlog)
- else
Any
%b.caret
%ul.dropdown-menu
%li
= link_to project_filter_path(milestone_id: nil) do
Any
= link_to project_filter_path(milestone_id: 0) do
None (backlog)
- project_active_milestones.each do |milestone|
%li
= link_to project_filter_path(milestone_id: milestone.id) do
%strong= milestone.title
%small.light= milestone.expires_at
.pull-right
= render 'shared/sort_dropdown'
.panel.panel-default .panel.panel-default
%ul.well-list.mr-list %ul.well-list.mr-list
= render @merge_requests = render @merge_requests
......
...@@ -5,9 +5,10 @@ describe IssuesFinder do ...@@ -5,9 +5,10 @@ describe IssuesFinder do
let(:user2) { create :user } let(:user2) { create :user }
let(:project1) { create(:project) } let(:project1) { create(:project) }
let(:project2) { create(:project) } let(:project2) { create(:project) }
let(:issue1) { create(:issue, assignee: user, project: project1) } let(:milestone) { create(:milestone, project: project1) }
let(:issue2) { create(:issue, assignee: user, project: project2) } let(:issue1) { create(:issue, author: user, assignee: user, project: project1, milestone: milestone) }
let(:issue3) { create(:issue, assignee: user2, project: project2) } let(:issue2) { create(:issue, author: user, assignee: user, project: project2) }
let(:issue3) { create(:issue, author: user2, assignee: user2, project: project2) }
before do before do
project1.team << [user, :master] project1.team << [user, :master]
...@@ -22,37 +23,59 @@ describe IssuesFinder do ...@@ -22,37 +23,59 @@ describe IssuesFinder do
issue3 issue3
end end
it 'should filter by all' do context 'scope: all' do
params = { scope: "all", state: 'opened' } it 'should filter by all' do
issues = IssuesFinder.new.execute(user, params) params = { scope: "all", state: 'opened' }
issues.size.should == 3 issues = IssuesFinder.new.execute(user, params)
end issues.size.should == 3
end
it 'should filter by assignee' do it 'should filter by assignee id' do
params = { scope: "assigned-to-me", state: 'opened' } params = { scope: "all", assignee_id: user.id, state: 'opened' }
issues = IssuesFinder.new.execute(user, params) issues = IssuesFinder.new.execute(user, params)
issues.size.should == 2 issues.size.should == 2
end end
it 'should filter by project' do it 'should filter by author id' do
params = { scope: "assigned-to-me", state: 'opened', project_id: project1.id } params = { scope: "all", author_id: user2.id, state: 'opened' }
issues = IssuesFinder.new.execute(user, params) issues = IssuesFinder.new.execute(user, params)
issues.size.should == 1 issues.should == [issue3]
end end
it 'should be empty for unauthorized user' do it 'should filter by milestone id' do
params = { scope: "all", state: 'opened' } params = { scope: "all", milestone_id: milestone.id, state: 'opened' }
issues = IssuesFinder.new.execute(nil, params) issues = IssuesFinder.new.execute(user, params)
issues.size.should be_zero issues.should == [issue1]
end
it 'should be empty for unauthorized user' do
params = { scope: "all", state: 'opened' }
issues = IssuesFinder.new.execute(nil, params)
issues.size.should be_zero
end
it 'should not include unauthorized issues' do
params = { scope: "all", state: 'opened' }
issues = IssuesFinder.new.execute(user2, params)
issues.size.should == 2
issues.should_not include(issue1)
issues.should include(issue2)
issues.should include(issue3)
end
end end
it 'should not include unauthorized issues' do context 'personal scope' do
params = { scope: "all", state: 'opened' } it 'should filter by assignee' do
issues = IssuesFinder.new.execute(user2, params) params = { scope: "assigned-to-me", state: 'opened' }
issues.size.should == 2 issues = IssuesFinder.new.execute(user, params)
issues.should_not include(issue1) issues.size.should == 2
issues.should include(issue2) end
issues.should include(issue3)
it 'should filter by project' do
params = { scope: "assigned-to-me", state: 'opened', project_id: project1.id }
issues = IssuesFinder.new.execute(user, params)
issues.size.should == 1
end
end end
end end
end end
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