Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
gitlab-ce
Commits
1d476b06
Commit
1d476b06
authored
Feb 17, 2016
by
Douglas Barbosa Alexandre
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Create a pending task when a user is mentioned on a note
parent
14fc05eb
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
146 additions
and
21 deletions
+146
-21
app/assets/stylesheets/pages/tasks.scss
app/assets/stylesheets/pages/tasks.scss
+24
-0
app/helpers/tasks_helper.rb
app/helpers/tasks_helper.rb
+16
-0
app/models/note.rb
app/models/note.rb
+2
-0
app/models/task.rb
app/models/task.rb
+6
-0
app/services/task_service.rb
app/services/task_service.rb
+14
-3
app/views/dashboard/tasks/_common.html.haml
app/views/dashboard/tasks/_common.html.haml
+17
-0
app/views/dashboard/tasks/_note.html.haml
app/views/dashboard/tasks/_note.html.haml
+26
-0
app/views/dashboard/tasks/_task.html.haml
app/views/dashboard/tasks/_task.html.haml
+4
-17
db/migrate/20160217174422_add_note_to_tasks.rb
db/migrate/20160217174422_add_note_to_tasks.rb
+5
-0
db/schema.rb
db/schema.rb
+3
-1
spec/models/note_spec.rb
spec/models/note_spec.rb
+2
-0
spec/models/task_spec.rb
spec/models/task_spec.rb
+16
-0
spec/services/task_service_spec.rb
spec/services/task_service_spec.rb
+11
-0
No files found.
app/assets/stylesheets/pages/tasks.scss
View file @
1d476b06
...
@@ -59,6 +59,15 @@
...
@@ -59,6 +59,15 @@
.task-note
{
.task-note
{
word-wrap
:
break-word
;
word-wrap
:
break-word
;
.md
{
color
:
#7f8fa4
;
font-size
:
$gl-font-size
;
p
{
color
:
#5c5d5e
;
}
}
pre
{
pre
{
border
:
none
;
border
:
none
;
background
:
#f9f9f9
;
background
:
#f9f9f9
;
...
@@ -68,10 +77,25 @@
...
@@ -68,10 +77,25 @@
overflow
:
hidden
;
overflow
:
hidden
;
}
}
.note-image-attach
{
margin-top
:
4px
;
margin-left
:
0px
;
max-width
:
200px
;
float
:
none
;
}
p
:last-child
{
p
:last-child
{
margin-bottom
:
0
;
margin-bottom
:
0
;
}
}
}
}
.task-note-icon
{
color
:
#777
;
float
:
left
;
font-size
:
$gl-font-size
;
line-height
:
16px
;
margin-right
:
5px
;
}
}
}
&
:last-child
{
border
:none
}
&
:last-child
{
border
:none
}
...
...
app/helpers/tasks_helper.rb
View file @
1d476b06
...
@@ -22,4 +22,20 @@ module TasksHelper
...
@@ -22,4 +22,20 @@ module TasksHelper
[
task
.
action_name
,
target
].
join
(
" "
)
[
task
.
action_name
,
target
].
join
(
" "
)
end
end
def
task_note_link_html
(
task
)
link_to
task_note_target_path
(
task
)
do
"#
#{
task
.
target_iid
}
"
end
end
def
task_note_target_path
(
task
)
polymorphic_path
([
task
.
project
.
namespace
.
becomes
(
Namespace
),
task
.
project
,
task
.
target
],
anchor:
dom_id
(
task
.
note
))
end
def
task_note
(
text
,
options
=
{})
text
=
first_line_in_markdown
(
text
,
150
,
options
)
sanitize
(
text
,
tags:
%w(a img b pre code p span)
)
end
end
end
app/models/note.rb
View file @
1d476b06
...
@@ -37,6 +37,8 @@ class Note < ActiveRecord::Base
...
@@ -37,6 +37,8 @@ class Note < ActiveRecord::Base
belongs_to
:author
,
class_name:
"User"
belongs_to
:author
,
class_name:
"User"
belongs_to
:updated_by
,
class_name:
"User"
belongs_to
:updated_by
,
class_name:
"User"
has_many
:tasks
,
dependent: :delete_all
delegate
:name
,
to: :project
,
prefix:
true
delegate
:name
,
to: :project
,
prefix:
true
delegate
:name
,
:email
,
to: :author
,
prefix:
true
delegate
:name
,
:email
,
to: :author
,
prefix:
true
...
...
app/models/task.rb
View file @
1d476b06
...
@@ -8,6 +8,7 @@
...
@@ -8,6 +8,7 @@
# target_id :integer not null
# target_id :integer not null
# target_type :string not null
# target_type :string not null
# author_id :integer
# author_id :integer
# note_id :integer
# action :integer
# action :integer
# state :string not null
# state :string not null
# created_at :datetime
# created_at :datetime
...
@@ -19,6 +20,7 @@ class Task < ActiveRecord::Base
...
@@ -19,6 +20,7 @@ class Task < ActiveRecord::Base
MENTIONED
=
2
MENTIONED
=
2
belongs_to
:author
,
class_name:
"User"
belongs_to
:author
,
class_name:
"User"
belongs_to
:note
belongs_to
:project
belongs_to
:project
belongs_to
:target
,
polymorphic:
true
,
touch:
true
belongs_to
:target
,
polymorphic:
true
,
touch:
true
belongs_to
:user
belongs_to
:user
...
@@ -52,6 +54,10 @@ class Task < ActiveRecord::Base
...
@@ -52,6 +54,10 @@ class Task < ActiveRecord::Base
target
.
respond_to?
:title
target
.
respond_to?
:title
end
end
def
note_text
note
.
try
(
:note
)
end
def
target_iid
def
target_iid
target
.
respond_to?
(
:iid
)
?
target
.
iid
:
target_id
target
.
respond_to?
(
:iid
)
?
target
.
iid
:
target_id
end
end
...
...
app/services/task_service.rb
View file @
1d476b06
...
@@ -77,7 +77,17 @@ class TaskService
...
@@ -77,7 +77,17 @@ class TaskService
def
new_note
(
note
)
def
new_note
(
note
)
# Skip system notes, like status changes and cross-references
# Skip system notes, like status changes and cross-references
unless
note
.
system
unless
note
.
system
mark_pending_tasks_as_done
(
note
.
noteable
,
note
.
author
)
project
=
note
.
project
target
=
note
.
noteable
author
=
note
.
author
mark_pending_tasks_as_done
(
target
,
author
)
mentioned_users
=
build_mentioned_users
(
project
,
note
,
author
)
mentioned_users
.
each
do
|
user
|
create_task
(
project
,
target
,
author
,
user
,
Task
::
MENTIONED
,
note
)
end
end
end
end
end
...
@@ -94,14 +104,15 @@ class TaskService
...
@@ -94,14 +104,15 @@ class TaskService
private
private
def
create_task
(
project
,
target
,
author
,
user
,
action
)
def
create_task
(
project
,
target
,
author
,
user
,
action
,
note
=
nil
)
attributes
=
{
attributes
=
{
project:
project
,
project:
project
,
user_id:
user
.
id
,
user_id:
user
.
id
,
author_id:
author
.
id
,
author_id:
author
.
id
,
target_id:
target
.
id
,
target_id:
target
.
id
,
target_type:
target
.
class
.
name
,
target_type:
target
.
class
.
name
,
action:
action
action:
action
,
note:
note
}
}
Task
.
create
(
attributes
)
Task
.
create
(
attributes
)
...
...
app/views/dashboard/tasks/_common.html.haml
0 → 100644
View file @
1d476b06
.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
.
pending?
.task-actions.pull-right
=
link_to
'Done'
,
[
:dashboard
,
task
],
method: :delete
,
class:
'btn'
-
if
task
.
body?
.task-body
.task-note
=
task
.
target
.
title
app/views/dashboard/tasks/_note.html.haml
0 → 100644
View file @
1d476b06
.task-title
%span
.author_name
=
link_to_author
task
%span
.task_label
{
class:
task
.
action_name
}
=
task_action_name
(
task
)
=
task_note_link_html
(
task
)
·
#{
time_ago_with_tooltip
(
task
.
created_at
)
}
-
if
task
.
pending?
.task-actions.pull-right
=
link_to
'Done'
,
[
:dashboard
,
task
],
method: :delete
,
class:
'btn'
.task-body
.task-note
.md
=
task_note
(
task
.
note_text
,
project:
task
.
project
)
-
note
=
task
.
note
-
if
note
.
attachment
.
url
-
if
note
.
attachment
.
image?
=
link_to
note
.
attachment
.
url
,
target:
'_blank'
do
=
image_tag
note
.
attachment
.
url
,
class:
'note-image-attach'
-
else
=
link_to
note
.
attachment
.
url
,
target:
"_blank"
,
class:
'note-file-attach'
do
%i
.fa.fa-paperclip
=
note
.
attachment_identifier
app/views/dashboard/tasks/_task.html.haml
View file @
1d476b06
...
@@ -2,20 +2,7 @@
...
@@ -2,20 +2,7 @@
.task-item
{
class:
"#{task.body? ? 'task-block' : 'task-inline' }"
}
.task-item
{
class:
"#{task.body? ? 'task-block' : 'task-inline' }"
}
=
image_tag
avatar_icon
(
task
.
author_email
,
40
),
class:
"avatar s40"
,
alt
:''
=
image_tag
avatar_icon
(
task
.
author_email
,
40
),
class:
"avatar s40"
,
alt
:''
.task-title
-
if
task
.
note
.
present?
%span
.author_name
=
link_to_author
task
=
render
'note'
,
task:
task
%span
.task_label
{
class:
task
.
action_name
}
-
else
=
task_action_name
(
task
)
=
render
'common'
,
task:
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
.
pending?
.task-actions.pull-right
=
link_to
'Done'
,
[
:dashboard
,
task
],
method: :delete
,
class:
'btn'
-
if
task
.
body?
.task-body
.task-note
=
task
.
target
.
title
db/migrate/20160217174422_add_note_to_tasks.rb
0 → 100644
View file @
1d476b06
class
AddNoteToTasks
<
ActiveRecord
::
Migration
def
change
add_reference
:tasks
,
:note
,
index:
true
end
end
db/schema.rb
View file @
1d476b06
...
@@ -11,7 +11,7 @@
...
@@ -11,7 +11,7 @@
#
#
# It's strongly recommended that you check this file into your version control system.
# It's strongly recommended that you check this file into your version control system.
ActiveRecord
::
Schema
.
define
(
version:
201602171
00506
)
do
ActiveRecord
::
Schema
.
define
(
version:
201602171
74422
)
do
# These are extensions that must be enabled in order to support this database
# These are extensions that must be enabled in order to support this database
enable_extension
"plpgsql"
enable_extension
"plpgsql"
...
@@ -834,9 +834,11 @@ ActiveRecord::Schema.define(version: 20160217100506) do
...
@@ -834,9 +834,11 @@ ActiveRecord::Schema.define(version: 20160217100506) do
t
.
string
"state"
,
null:
false
t
.
string
"state"
,
null:
false
t
.
datetime
"created_at"
t
.
datetime
"created_at"
t
.
datetime
"updated_at"
t
.
datetime
"updated_at"
t
.
integer
"note_id"
end
end
add_index
"tasks"
,
[
"author_id"
],
name:
"index_tasks_on_author_id"
,
using: :btree
add_index
"tasks"
,
[
"author_id"
],
name:
"index_tasks_on_author_id"
,
using: :btree
add_index
"tasks"
,
[
"note_id"
],
name:
"index_tasks_on_note_id"
,
using: :btree
add_index
"tasks"
,
[
"project_id"
],
name:
"index_tasks_on_project_id"
,
using: :btree
add_index
"tasks"
,
[
"project_id"
],
name:
"index_tasks_on_project_id"
,
using: :btree
add_index
"tasks"
,
[
"state"
],
name:
"index_tasks_on_state"
,
using: :btree
add_index
"tasks"
,
[
"state"
],
name:
"index_tasks_on_state"
,
using: :btree
add_index
"tasks"
,
[
"target_type"
,
"target_id"
],
name:
"index_tasks_on_target_type_and_target_id"
,
using: :btree
add_index
"tasks"
,
[
"target_type"
,
"target_id"
],
name:
"index_tasks_on_target_type_and_target_id"
,
using: :btree
...
...
spec/models/note_spec.rb
View file @
1d476b06
...
@@ -26,6 +26,8 @@ describe Note, models: true do
...
@@ -26,6 +26,8 @@ describe Note, models: true do
it
{
is_expected
.
to
belong_to
(
:project
)
}
it
{
is_expected
.
to
belong_to
(
:project
)
}
it
{
is_expected
.
to
belong_to
(
:noteable
)
}
it
{
is_expected
.
to
belong_to
(
:noteable
)
}
it
{
is_expected
.
to
belong_to
(
:author
).
class_name
(
'User'
)
}
it
{
is_expected
.
to
belong_to
(
:author
).
class_name
(
'User'
)
}
it
{
is_expected
.
to
have_many
(
:tasks
).
dependent
(
:delete_all
)
}
end
end
describe
'validation'
do
describe
'validation'
do
...
...
spec/models/task_spec.rb
View file @
1d476b06
...
@@ -8,6 +8,7 @@
...
@@ -8,6 +8,7 @@
# target_id :integer not null
# target_id :integer not null
# target_type :string not null
# target_type :string not null
# author_id :integer
# author_id :integer
# note_id :integer
# action :integer
# action :integer
# state :string not null
# state :string not null
# created_at :datetime
# created_at :datetime
...
@@ -19,6 +20,7 @@ require 'spec_helper'
...
@@ -19,6 +20,7 @@ require 'spec_helper'
describe
Task
,
models:
true
do
describe
Task
,
models:
true
do
describe
'relationships'
do
describe
'relationships'
do
it
{
is_expected
.
to
belong_to
(
:author
).
class_name
(
"User"
)
}
it
{
is_expected
.
to
belong_to
(
:author
).
class_name
(
"User"
)
}
it
{
is_expected
.
to
belong_to
(
:note
)
}
it
{
is_expected
.
to
belong_to
(
:project
)
}
it
{
is_expected
.
to
belong_to
(
:project
)
}
it
{
is_expected
.
to
belong_to
(
:target
).
touch
(
true
)
}
it
{
is_expected
.
to
belong_to
(
:target
).
touch
(
true
)
}
it
{
is_expected
.
to
belong_to
(
:user
)
}
it
{
is_expected
.
to
belong_to
(
:user
)
}
...
@@ -48,6 +50,20 @@ describe Task, models: true do
...
@@ -48,6 +50,20 @@ describe Task, models: true do
it
'returns false when target does not respond to title'
it
'returns false when target does not respond to title'
end
end
describe
'#note_text'
do
it
'returns nil when note is blank'
do
subject
.
note
=
nil
expect
(
subject
.
note_text
).
to
be_nil
end
it
'returns note when note is present'
do
subject
.
note
=
build
(
:note
,
note:
'quick fix'
)
expect
(
subject
.
note_text
).
to
eq
'quick fix'
end
end
describe
'#target_iid'
do
describe
'#target_iid'
do
it
'returns target.iid when target respond to iid'
it
'returns target.iid when target respond to iid'
it
'returns target_id when target does not respond to iid'
it
'returns target_id when target does not respond to iid'
...
...
spec/services/task_service_spec.rb
View file @
1d476b06
...
@@ -128,6 +128,17 @@ describe TaskService, services: true do
...
@@ -128,6 +128,17 @@ describe TaskService, services: true do
expect
(
first_pending_task
.
reload
).
to
be_pending
expect
(
first_pending_task
.
reload
).
to
be_pending
expect
(
second_pending_task
.
reload
).
to
be_pending
expect
(
second_pending_task
.
reload
).
to
be_pending
end
end
it
'creates a task for each valid mentioned user'
do
note
.
update_attribute
(
:note
,
mentions
)
service
.
new_note
(
note
)
should_create_task
(
user:
michael
,
target:
issue
,
author:
john_doe
,
action:
Task
::
MENTIONED
,
note:
note
)
should_create_task
(
user:
author
,
target:
issue
,
author:
john_doe
,
action:
Task
::
MENTIONED
,
note:
note
)
should_not_create_task
(
user:
john_doe
,
target:
issue
,
author:
john_doe
,
action:
Task
::
MENTIONED
,
note:
note
)
should_not_create_task
(
user:
stranger
,
target:
issue
,
author:
john_doe
,
action:
Task
::
MENTIONED
,
note:
note
)
end
end
end
end
end
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment