Add filters by project, author, type, and action to task queue page list

parent c4c4b808
class Dashboard::TasksController < Dashboard::ApplicationController
def index
@tasks = case params[:state]
when 'done'
current_user.tasks.done
else
current_user.tasks.pending
end
@tasks = TasksFinder.new(current_user, params).execute
@tasks = @tasks.page(params[:page]).per(PER_PAGE)
end
......
# TasksFinder
#
# Used to filter Tasks by set of params
#
# Arguments:
# current_user - which user use
# params:
# action_id: integer
# author_id: integer
# project_id; integer
# state: 'pending' or 'done'
# type: 'Issue' or 'MergeRequest'
#
class TasksFinder
NONE = '0'
attr_accessor :current_user, :params
def initialize(current_user, params)
@current_user = current_user
@params = params
end
def execute
items = current_user.tasks
items = by_action_id(items)
items = by_author(items)
items = by_project(items)
items = by_state(items)
items = by_type(items)
items
end
private
def action_id?
action_id.present? && [Task::ASSIGNED, Task::MENTIONED].include?(action_id.to_i)
end
def action_id
params[:action_id]
end
def author?
params[:author_id].present?
end
def author
return @author if defined?(@author)
@author =
if author? && params[:author_id] != NONE
User.find(params[:author_id])
else
nil
end
end
def project?
params[:project_id].present?
end
def project
return @project if defined?(@project)
if project?
@project = Project.find(params[:project_id])
unless Ability.abilities.allowed?(current_user, :read_project, @project)
@project = nil
end
else
@project = nil
end
@project
end
def type?
type.present? && ['Issue', 'MergeRequest'].include?(type)
end
def type
params[:type]
end
def by_action_id(items)
if action_id?
items = items.where(action: action_id)
end
items
end
def by_author(items)
if author?
items = items.where(author_id: author.try(:id))
end
items
end
def by_project(items)
if project?
items = items.where(project: project)
end
items
end
def by_state(items)
case params[:state]
when 'done'
items.done
else
items.pending
end
end
def by_type(items)
if type?
items = items.where(target_type: type)
end
items
end
end
......@@ -38,4 +38,37 @@ module TasksHelper
text = first_line_in_markdown(text, 150, options)
sanitize(text, tags: %w(a img b pre code p span))
end
def task_actions_options
actions = [
OpenStruct.new(id: '', title: 'Any Action'),
OpenStruct.new(id: Task::ASSIGNED, title: 'Assigned'),
OpenStruct.new(id: Task::MENTIONED, title: 'Mentioned')
]
options_from_collection_for_select(actions, 'id', 'title', params[:action_id])
end
def task_projects_options
projects = current_user.authorized_projects.sorted_by_activity.non_archived
projects = projects.includes(:namespace)
projects = projects.map do |project|
OpenStruct.new(id: project.id, title: project.name_with_namespace)
end
projects.unshift(OpenStruct.new(id: '', title: 'Any Project'))
options_from_collection_for_select(projects, 'id', 'title', params[:project_id])
end
def task_types_options
types = [
OpenStruct.new(title: 'Any Type', name: ''),
OpenStruct.new(title: 'Issue', name: 'Issue'),
OpenStruct.new(title: 'Merge Request', name: 'MergeRequest')
]
options_from_collection_for_select(types, 'name', 'title', params[:type])
end
end
......@@ -3,12 +3,37 @@
.top-area
%ul.nav-links
%li{class: ("active" if params[:state].blank? || params[:state] == 'pending')}
= link_to dashboard_tasks_path(state: 'pending') do
Tasks (#{tasks_pending_count})
%li{class: ("active" if params[:state] == 'done')}
= link_to dashboard_tasks_path(state: 'done') do
Done (#{tasks_done_count})
%li{class: ('active' if params[:state].blank? || params[:state] == 'pending')}
= link_to page_filter_path(state: 'pending') do
%span
Tasks
%span{class: 'badge'}
= tasks_pending_count
%li{class: ('active' if params[:state] == 'done')}
= link_to page_filter_path(state: 'done') do
%span
Done
%span{class: 'badge'}
= tasks_done_count
.tasks-filters
.gray-content-block.second-block
= form_tag page_filter_path(without: [:assignee_id, :milestone_title, :label_name, :scope, :sort]), method: :get, class: 'filter-form' do
.filter-item.inline
= select_tag('project_id', task_projects_options,
class: 'select2 trigger-submit', include_blank: true,
data: {placeholder: 'Project'})
.filter-item.inline
= users_select_tag(:author_id, selected: params[:author_id],
placeholder: 'Author', class: 'trigger-submit', any_user: "Any Author", first_user: true, current_user: true)
.filter-item.inline
= select_tag('type', task_types_options,
class: 'select2 trigger-submit', include_blank: true,
data: {placeholder: 'Type'})
.filter-item.inline.actions-filter
= select_tag('action_id', task_actions_options,
class: 'select2 trigger-submit', include_blank: true,
data: {placeholder: 'Action'})
.tasks
- if @tasks.any?
......@@ -23,3 +48,11 @@
= paginate @tasks, theme: "gitlab"
- else
.nothing-here-block No tasks to show
:javascript
new UsersSelect();
$('form.filter-form').on('submit', function (event) {
event.preventDefault();
Turbolinks.visit(this.action + '&' + $(this).serialize());
});
......@@ -4,6 +4,9 @@ Feature: Dashboard Task Queue
Given I sign in as a user
And I own project "Shop"
And "John Doe" is a developer of project "Shop"
And "Mary Jane" is a developer of project "Shop"
And "Mary Jane" owns private project "Enterprise"
And I am a developer of project "Enterprise"
And I have pending tasks
And I visit dashboard task queue page
......@@ -13,3 +16,23 @@ Feature: Dashboard Task Queue
And I mark the pending task as done
And I click on the "Done" tab
Then I should see all tasks marked as done
@javascript
Scenario: I filter by project
Given I filter by "Enterprise"
Then I should not see tasks
@javascript
Scenario: I filter by author
Given I filter by "John Doe"
Then I should not see tasks related to "Mary Jane" in the list
@javascript
Scenario: I filter by type
Given I filter by "Issue"
Then I should not see tasks related to "Merge Requests" in the list
@javascript
Scenario: I filter by action
Given I filter by "Mentioned"
Then I should not see tasks related to "Assignments" in the list
......@@ -3,58 +3,126 @@ class Spinach::Features::DashboardTaskQueue < Spinach::FeatureSteps
include SharedPaths
include SharedProject
include SharedUser
include Select2Helper
step '"John Doe" is a developer of project "Shop"' do
project.team << [john_doe, :developer]
end
step 'I am a developer of project "Enterprise"' do
enterprise.team << [current_user, :developer]
end
step '"Mary Jane" is a developer of project "Shop"' do
project.team << [john_doe, :developer]
end
step 'I have pending tasks' do
create(:task, user: current_user, project: project, author: john_doe, target: assigned_issue, action: Task::ASSIGNED)
create(:task, user: current_user, project: project, author: mary_jane, target: issue, action: Task::MENTIONED)
create(:task, user: current_user, project: project, author: john_doe, target: issue, action: Task::ASSIGNED)
note = create(:note, author: john_doe, noteable: issue, note: "#{current_user.to_reference} Wdyt?")
create(:task, user: current_user, project: project, author: john_doe, target: issue, action: Task::MENTIONED, note: note)
create(:task, user: current_user, project: project, author: john_doe, target: merge_request, action: Task::ASSIGNED)
end
step 'I should see pending tasks assigned to me' do
expect(page).to have_link 'Tasks (1)'
expect(page).to have_link 'Done (0)'
page.within('.tasks') do
expect(page).to have_content project.name_with_namespace
expect(page).to have_content "John Doe assigned issue ##{assigned_issue.iid}"
expect(page).to have_content(assigned_issue.title[0..10])
expect(page).to have_link 'Done'
end
expect(page).to have_content 'Tasks 4'
expect(page).to have_content 'Done 0'
expect(page).to have_link project.name_with_namespace
should_see_task(1, "John Doe assigned merge request ##{merge_request.iid}", merge_request.title)
should_see_task(2, "John Doe mentioned on issue ##{issue.iid}", "#{current_user.to_reference} Wdyt?")
should_see_task(3, "John Doe assigned issue ##{issue.iid}", issue.title)
should_see_task(4, "Mary Jane mentioned on issue ##{issue.iid}", issue.title)
end
step 'I mark the pending task as done' do
click_link 'Done'
page.within('.task:nth-child(1)') do
click_link 'Done'
end
expect(page).to have_content 'Task was successfully marked as done.'
expect(page).to have_link 'Tasks (0)'
expect(page).to have_link 'Done (1)'
expect(page).to have_content 'No tasks to show'
expect(page).to have_content 'Tasks 3'
expect(page).to have_content 'Done 1'
should_not_see_task "John Doe assigned merge request ##{merge_request.iid}"
end
step 'I click on the "Done" tab' do
click_link 'Done (1)'
click_link 'Done 1'
end
step 'I should see all tasks marked as done' do
page.within('.tasks') do
expect(page).to have_content project.name_with_namespace
expect(page).to have_content "John Doe assigned issue ##{assigned_issue.iid}"
expect(page).to have_content(assigned_issue.title[0..10])
expect(page).not_to have_link 'Done'
expect(page).to have_link project.name_with_namespace
should_see_task(1, "John Doe assigned merge request ##{merge_request.iid}", merge_request.title, false)
end
step 'I filter by "Enterprise"' do
select2(enterprise.id, from: "#project_id")
end
step 'I filter by "John Doe"' do
select2(john_doe.id, from: "#author_id")
end
step 'I filter by "Issue"' do
select2('Issue', from: "#type")
end
step 'I filter by "Mentioned"' do
select2("#{Task::MENTIONED}", from: '#action_id')
end
step 'I should not see tasks' do
expect(page).to have_content 'No tasks to show'
end
step 'I should not see tasks related to "Mary Jane" in the list' do
should_not_see_task "Mary Jane mentioned on issue ##{issue.iid}"
end
step 'I should not see tasks related to "Merge Requests" in the list' do
should_not_see_task "John Doe assigned merge request ##{merge_request.iid}"
end
step 'I should not see tasks related to "Assignments" in the list' do
should_not_see_task "John Doe assigned merge request ##{merge_request.iid}"
should_not_see_task "John Doe assigned issue ##{issue.iid}"
end
def should_see_task(position, title, body, pending = true)
page.within(".task:nth-child(#{position})") do
expect(page).to have_content title
expect(page).to have_content body
if pending
expect(page).to have_link 'Done'
else
expect(page).to_not have_link 'Done'
end
end
end
def assigned_issue
@assigned_issue ||= create(:issue, assignee: current_user, project: project)
def should_not_see_task(title)
expect(page).not_to have_content title
end
def john_doe
@john_doe ||= user_exists("John Doe", { username: "john_doe" })
end
def project
@project ||= create(:project, name: "Shop")
def mary_jane
@mary_jane ||= user_exists("Mary Jane", { username: "mary_jane" })
end
def enterprise
@enterprise ||= Project.find_by(name: 'Enterprise')
end
def issue
@issue ||= create(:issue, assignee: current_user, project: project)
end
def merge_request
@merge_request ||= create(:merge_request, assignee: current_user, source_project: project)
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