summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Barbosa Alexandre <dbalexandre@gmail.com>2016-02-18 01:20:31 -0200
committerDouglas Barbosa Alexandre <dbalexandre@gmail.com>2016-02-20 12:12:05 -0200
commit07eb334c2546294acea43e85308bec907b13467c (patch)
tree44e958d4afec67648365270c79257e21d049e75f
parentc4c4b808f3ff7944e6b4216e910cc40a0fa2ebec (diff)
downloadgitlab-ce-07eb334c2546294acea43e85308bec907b13467c.tar.gz
Add filters by project, author, type, and action to task queue page list
-rw-r--r--app/controllers/dashboard/tasks_controller.rb8
-rw-r--r--app/finders/tasks_finder.rb129
-rw-r--r--app/helpers/tasks_helper.rb33
-rw-r--r--app/views/dashboard/tasks/index.html.haml45
-rw-r--r--features/dashboard/task_queue.feature23
-rw-r--r--features/steps/dashboard/task_queue.rb116
6 files changed, 317 insertions, 37 deletions
diff --git a/app/controllers/dashboard/tasks_controller.rb b/app/controllers/dashboard/tasks_controller.rb
index e3245609204..a8884be54e4 100644
--- a/app/controllers/dashboard/tasks_controller.rb
+++ b/app/controllers/dashboard/tasks_controller.rb
@@ -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
diff --git a/app/finders/tasks_finder.rb b/app/finders/tasks_finder.rb
new file mode 100644
index 00000000000..2a32e977c24
--- /dev/null
+++ b/app/finders/tasks_finder.rb
@@ -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
diff --git a/app/helpers/tasks_helper.rb b/app/helpers/tasks_helper.rb
index 6975c1d1604..59c7d93e65e 100644
--- a/app/helpers/tasks_helper.rb
+++ b/app/helpers/tasks_helper.rb
@@ -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
diff --git a/app/views/dashboard/tasks/index.html.haml b/app/views/dashboard/tasks/index.html.haml
index 2f582009288..16e7b4ae0c5 100644
--- a/app/views/dashboard/tasks/index.html.haml
+++ b/app/views/dashboard/tasks/index.html.haml
@@ -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());
+ });
diff --git a/features/dashboard/task_queue.feature b/features/dashboard/task_queue.feature
index 42b4a86e498..8972a148289 100644
--- a/features/dashboard/task_queue.feature
+++ b/features/dashboard/task_queue.feature
@@ -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
diff --git a/features/steps/dashboard/task_queue.rb b/features/steps/dashboard/task_queue.rb
index 8695dd5cfb1..53920f585dc 100644
--- a/features/steps/dashboard/task_queue.rb
+++ b/features/steps/dashboard/task_queue.rb
@@ -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