Add tasks queue list page
This commit is contained in:
parent
41d8f5649e
commit
7cafa2ce92
8 changed files with 211 additions and 0 deletions
90
app/assets/stylesheets/pages/tasks.scss
Normal file
90
app/assets/stylesheets/pages/tasks.scss
Normal file
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
* Dashboard tasks queue
|
||||
*
|
||||
*/
|
||||
.tasks {
|
||||
.panel {
|
||||
border-top: none;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.task-item {
|
||||
font-size: $gl-font-size;
|
||||
padding: $gl-padding-top 0 $gl-padding-top ($gl-avatar-size + $gl-padding-top);
|
||||
border-bottom: 1px solid $table-border-color;
|
||||
color: #7f8fa4;
|
||||
|
||||
&.task-inline {
|
||||
.avatar {
|
||||
position: relative;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.task-title {
|
||||
line-height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: #4c4e54;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
margin-left: -($gl-avatar-size + $gl-padding-top);
|
||||
}
|
||||
|
||||
.task-title {
|
||||
@include str-truncated(calc(100% - 174px));
|
||||
font-weight: 600;
|
||||
|
||||
.author_name {
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.task-body {
|
||||
margin-right: 174px;
|
||||
|
||||
.task-note {
|
||||
word-wrap: break-word;
|
||||
|
||||
pre {
|
||||
border: none;
|
||||
background: #f9f9f9;
|
||||
border-radius: 0;
|
||||
color: #777;
|
||||
margin: 0 20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child { border:none }
|
||||
}
|
||||
|
||||
@media (max-width: $screen-xs-max) {
|
||||
.task-item {
|
||||
padding-left: $gl-padding;
|
||||
|
||||
.task-title {
|
||||
white-space: normal;
|
||||
overflow: visible;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.task-body {
|
||||
margin: 0;
|
||||
border-left: 2px solid #DDD;
|
||||
padding-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
15
app/controllers/dashboard/tasks_controller.rb
Normal file
15
app/controllers/dashboard/tasks_controller.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
class Dashboard::TasksController < Dashboard::ApplicationController
|
||||
def index
|
||||
@tasks = case params[:state]
|
||||
when 'done'
|
||||
current_user.tasks.done
|
||||
else
|
||||
current_user.tasks.pending
|
||||
end
|
||||
|
||||
@tasks = @tasks.page(params[:page]).per(PER_PAGE)
|
||||
|
||||
@pending_count = current_user.tasks.pending.count
|
||||
@done_count = current_user.tasks.done.count
|
||||
end
|
||||
end
|
17
app/helpers/tasks_helper.rb
Normal file
17
app/helpers/tasks_helper.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
module TasksHelper
|
||||
def link_to_author(task)
|
||||
author = task.author
|
||||
|
||||
if author
|
||||
link_to author.name, user_path(author.username)
|
||||
else
|
||||
task.author_name
|
||||
end
|
||||
end
|
||||
|
||||
def task_action_name(task)
|
||||
target = task.target_type.titleize.downcase
|
||||
|
||||
[task.action_name, target].join(" ")
|
||||
end
|
||||
end
|
|
@ -15,15 +15,38 @@
|
|||
#
|
||||
|
||||
class Task < ActiveRecord::Base
|
||||
ASSIGNED = 1
|
||||
|
||||
belongs_to :author, class_name: "User"
|
||||
belongs_to :project
|
||||
belongs_to :target, polymorphic: true, touch: true
|
||||
belongs_to :user
|
||||
|
||||
delegate :name, :email, to: :author, prefix: true, allow_nil: true
|
||||
|
||||
validates :action, :project, :target, :user, presence: true
|
||||
|
||||
default_scope { reorder(id: :desc) }
|
||||
|
||||
scope :pending, -> { with_state(:pending) }
|
||||
scope :done, -> { with_state(:done) }
|
||||
|
||||
state_machine :state, initial: :pending do
|
||||
state :pending
|
||||
state :done
|
||||
end
|
||||
|
||||
def action_name
|
||||
case action
|
||||
when ASSIGNED then 'assigned'
|
||||
end
|
||||
end
|
||||
|
||||
def body?
|
||||
target.respond_to? :title
|
||||
end
|
||||
|
||||
def target_iid
|
||||
target.respond_to?(:iid) ? target.iid : target_id
|
||||
end
|
||||
end
|
||||
|
|
17
app/views/dashboard/tasks/_task.html.haml
Normal file
17
app/views/dashboard/tasks/_task.html.haml
Normal file
|
@ -0,0 +1,17 @@
|
|||
%li{class: "task task-#{task.done? ? 'done' : 'pending'}", id: dom_id(task) }
|
||||
.task-item{class: "#{task.body? ? 'task-block' : 'task-inline' }"}
|
||||
= image_tag avatar_icon(task.author_email, 40), class: "avatar s40", alt:''
|
||||
|
||||
.task-title
|
||||
%span.author_name= link_to_author task
|
||||
%span.task_label{class: task.action_name}
|
||||
= task_action_name(task)
|
||||
|
||||
%strong= link_to "##{task.target_iid}", [task.project.namespace.becomes(Namespace), task.project, task.target]
|
||||
|
||||
· #{time_ago_with_tooltip(task.created_at)}
|
||||
|
||||
- if task.body?
|
||||
.task-body
|
||||
.task-note
|
||||
= task.target.title
|
25
app/views/dashboard/tasks/index.html.haml
Normal file
25
app/views/dashboard/tasks/index.html.haml
Normal file
|
@ -0,0 +1,25 @@
|
|||
- page_title "Tasks Queue"
|
||||
- header_title "Tasks Queue", dashboard_tasks_path
|
||||
|
||||
.top-area
|
||||
%ul.nav-links
|
||||
%li{class: ("active" if params[:state].blank? || params[:state] == 'pending')}
|
||||
= link_to dashboard_tasks_path(state: 'pending') do
|
||||
Tasks (#{@pending_count})
|
||||
%li{class: ("active" if params[:state] == 'done')}
|
||||
= link_to dashboard_tasks_path(state: 'done') do
|
||||
Done (#{@done_count})
|
||||
|
||||
.tasks
|
||||
- if @tasks.any?
|
||||
- @tasks.group_by(&:project).each do |group|
|
||||
.panel.panel-default
|
||||
- project = group[0]
|
||||
.panel-heading
|
||||
= link_to project.name_with_namespace, namespace_project_path(project.namespace, project)
|
||||
|
||||
%ul.well-list.tasks-list
|
||||
= render group[1]
|
||||
= paginate @tasks, theme: "gitlab"
|
||||
- else
|
||||
.nothing-here-block No tasks to show
|
|
@ -333,6 +333,7 @@ Rails.application.routes.draw do
|
|||
|
||||
resources :groups, only: [:index]
|
||||
resources :snippets, only: [:index]
|
||||
resources :tasks, only: [:index]
|
||||
|
||||
resources :projects, only: [:index] do
|
||||
collection do
|
||||
|
|
|
@ -24,9 +24,32 @@ describe Task, models: true do
|
|||
it { is_expected.to belong_to(:user) }
|
||||
end
|
||||
|
||||
describe 'respond to' do
|
||||
it { is_expected.to respond_to(:author_name) }
|
||||
it { is_expected.to respond_to(:author_email) }
|
||||
end
|
||||
|
||||
describe 'validations' do
|
||||
it { is_expected.to validate_presence_of(:action) }
|
||||
it { is_expected.to validate_presence_of(:target) }
|
||||
it { is_expected.to validate_presence_of(:user) }
|
||||
end
|
||||
|
||||
describe '#action_name' do
|
||||
it 'returns assigned when action is assigned' do
|
||||
subject.action = Task::ASSIGNED
|
||||
|
||||
expect(subject.action_name).to eq 'assigned'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#body?' do
|
||||
it 'returns true when target respond to title'
|
||||
it 'returns false when target does not respond to title'
|
||||
end
|
||||
|
||||
describe '#target_iid' do
|
||||
it 'returns target.iid when target respond to iid'
|
||||
it 'returns target_id when target does not respond to iid'
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue