Add filters by project, author, type, and action to task queue page list
This commit is contained in:
parent
c4c4b808f3
commit
07eb334c25
|
@ -1,12 +1,6 @@
|
|||
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
|
||||
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
# 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)'
|
||||
expect(page).to have_content 'Tasks 4'
|
||||
expect(page).to have_content '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_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
|
||||
|
|
Loading…
Reference in New Issue