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
Jérome Perrin
gitlab-ce
Commits
c1fe066b
Commit
c1fe066b
authored
Jul 14, 2016
by
Phil Hughes
Committed by
Douwe Maan
Jul 24, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added resolve button to discussions
Top count displays how many resolved discussions
parent
43131802
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
129 additions
and
65 deletions
+129
-65
app/assets/javascripts/line_comments/application.js.coffee
app/assets/javascripts/line_comments/application.js.coffee
+4
-3
app/assets/javascripts/line_comments/components/resolve_all.js.coffee
...avascripts/line_comments/components/resolve_all.js.coffee
+11
-16
app/assets/javascripts/line_comments/components/resolve_btn.js.coffee
...avascripts/line_comments/components/resolve_btn.js.coffee
+5
-4
app/assets/javascripts/line_comments/components/resolve_count.js.coffee
...ascripts/line_comments/components/resolve_count.js.coffee
+17
-0
app/assets/javascripts/line_comments/services/resolve.js.coffee
...sets/javascripts/line_comments/services/resolve.js.coffee
+13
-6
app/assets/javascripts/line_comments/stores/comments.js.coffee
...ssets/javascripts/line_comments/stores/comments.js.coffee
+14
-14
app/assets/javascripts/merge_request_tabs.js.coffee
app/assets/javascripts/merge_request_tabs.js.coffee
+5
-0
app/assets/javascripts/notes.js.coffee
app/assets/javascripts/notes.js.coffee
+9
-7
app/assets/stylesheets/pages/note_form.scss
app/assets/stylesheets/pages/note_form.scss
+21
-0
app/helpers/notes_helper.rb
app/helpers/notes_helper.rb
+2
-4
app/views/discussions/_diff_discussion.html.haml
app/views/discussions/_diff_discussion.html.haml
+7
-1
app/views/discussions/_parallel_diff_discussion.html.haml
app/views/discussions/_parallel_diff_discussion.html.haml
+12
-2
app/views/projects/merge_requests/_show.html.haml
app/views/projects/merge_requests/_show.html.haml
+4
-7
app/views/projects/notes/_note.html.haml
app/views/projects/notes/_note.html.haml
+1
-1
app/views/projects/notes/discussions/_resolve_all.html.haml
app/views/projects/notes/discussions/_resolve_all.html.haml
+4
-0
No files found.
app/assets/javascripts/line_comments/application.js.coffee
View file @
c1fe066b
...
...
@@ -6,11 +6,12 @@
$
=>
@
DiffNotesApp
=
new
Vue
el
:
'#
notes
'
el
:
'#
diff-comments-app
'
components
:
'resolve-btn'
:
ResolveBtn
'resolve-all'
:
ResolveAll
new
Vue
el
:
'#resolve-
all
-app'
el
:
'#resolve-
count
-app'
components
:
'resolve-
all'
:
ResolveAll
'resolve-
count'
:
ResolveCount
app/assets/javascripts/line_comments/components/resolve_all.js.coffee
View file @
c1fe066b
@
ResolveAll
=
Vue
.
extend
props
:
discussionId
:
String
namespace
:
String
data
:
->
comments
:
CommentsStore
.
state
loading
:
false
props
:
namespace
:
String
computed
:
resolved
:
->
resolvedCount
=
0
for
noteId
,
resolved
of
this
.
comments
resolvedCount
++
if
resolved
resolvedCount
commentsCount
:
->
Object
.
keys
(
this
.
comments
).
length
buttonText
:
->
if
this
.
allResolved
then
'Un-resolve all'
else
'Resolve all'
allResolved
:
->
this
.
resolved
is
this
.
commentsCount
isResolved
=
true
for
noteId
,
resolved
of
this
.
comments
[
this
.
discussionId
]
isResolved
=
false
unless
resolved
isResolved
buttonText
:
->
if
this
.
allResolved
then
"Un-resolve all"
else
"Resolve all"
methods
:
updateAll
:
->
ids
=
CommentsStore
.
getAllForState
(
this
.
allResolved
)
resolve
:
->
this
.
loading
=
true
ResolveService
.
resolveAll
(
this
.
namespace
,
ids
,
!
this
.
allResolved
)
.
resolveAll
(
this
.
namespace
,
this
.
discussionId
,
this
.
allResolved
)
.
then
=>
this
.
loading
=
false
app/assets/javascripts/line_comments/components/resolve_btn.js.coffee
View file @
c1fe066b
@
ResolveBtn
=
Vue
.
extend
props
:
noteId
:
Number
discussionId
:
String
resolved
:
Boolean
namespace
:
String
data
:
->
...
...
@@ -9,7 +10,7 @@
computed
:
buttonText
:
->
if
this
.
isResolved
then
"Mark as un-resolved"
else
"Mark as resolved"
isResolved
:
->
this
.
comments
[
this
.
noteId
]
isResolved
:
->
CommentsStore
.
get
(
this
.
discussionId
,
this
.
noteId
)
methods
:
updateTooltip
:
->
$
(
this
.
$els
.
button
)
...
...
@@ -18,13 +19,13 @@
resolve
:
->
this
.
loading
=
true
ResolveService
.
resolve
(
this
.
namespace
,
this
.
noteId
,
!
this
.
isResolved
)
.
resolve
(
this
.
namespace
,
this
.
discussionId
,
this
.
noteId
,
!
this
.
isResolved
)
.
then
=>
this
.
loading
=
false
this
.
$nextTick
this
.
updateTooltip
compiled
:
->
$
(
this
.
$els
.
button
).
tooltip
()
destroyed
:
->
CommentsStore
.
delete
(
this
.
noteId
)
CommentsStore
.
delete
(
this
.
discussionId
,
this
.
noteId
)
created
:
->
CommentsStore
.
create
(
this
.
noteId
,
this
.
resolved
)
CommentsStore
.
create
(
this
.
discussionId
,
this
.
noteId
,
this
.
resolved
)
app/assets/javascripts/line_comments/components/resolve_count.js.coffee
0 → 100644
View file @
c1fe066b
@
ResolveCount
=
Vue
.
extend
data
:
->
comments
:
CommentsStore
.
state
loading
:
false
computed
:
resolved
:
->
resolvedCount
=
0
for
discussionId
,
comments
of
this
.
comments
resolved
=
true
for
noteId
,
resolved
of
comments
resolved
=
false
unless
resolved
resolvedCount
++
if
resolved
resolvedCount
commentsCount
:
->
Object
.
keys
(
this
.
comments
).
length
allResolved
:
->
this
.
resolved
is
this
.
commentsCount
app/assets/javascripts/line_comments/services/resolve.js.coffee
View file @
c1fe066b
...
...
@@ -12,20 +12,27 @@ class ResolveService
Vue
.
http
.
headers
.
common
[
'X-CSRF-Token'
]
=
$
.
rails
.
csrfToken
()
@
resource
=
Vue
.
resource
(
'notes{/id}'
,
{},
actions
)
resolve
:
(
namespace
,
i
d
,
resolve
)
->
resolve
:
(
namespace
,
discussionId
,
noteI
d
,
resolve
)
->
Vue
.
http
.
options
.
root
=
"/
#{
namespace
}
"
@
resource
.
resolve
({
id
:
id
},
{
resolved
:
resolve
})
.
resolve
({
id
:
noteId
},
{
discussion
:
discussionId
,
resolved
:
resolve
})
.
then
(
response
)
->
if
response
.
status
is
200
CommentsStore
.
update
(
i
d
,
resolve
)
CommentsStore
.
update
(
discussionId
,
noteI
d
,
resolve
)
resolveAll
:
(
namespace
,
ids
,
r
esolve
)
->
resolveAll
:
(
namespace
,
discussionId
,
allR
esolve
)
->
Vue
.
http
.
options
.
root
=
"/
#{
namespace
}
"
ids
=
[]
for
noteId
,
resolved
of
CommentsStore
.
state
[
discussionId
]
ids
.
push
(
noteId
)
if
resolved
is
allResolve
@
resource
.
all
({},
{
ids
:
ids
,
resolve
:
r
esolve
})
.
all
({},
{
ids
:
ids
,
discussion
:
discussionId
,
resolved
:
!
allR
esolve
})
.
then
(
response
)
->
CommentsStore
.
updateAll
(
resolve
)
if
response
.
status
is
200
for
noteId
in
ids
CommentsStore
.
update
(
discussionId
,
noteId
,
!
allResolve
)
$
->
@
ResolveService
=
new
ResolveService
()
app/assets/javascripts/line_comments/stores/comments.js.coffee
View file @
c1fe066b
@
CommentsStore
=
state
:
{}
create
:
(
id
,
resolve
d
)
->
Vue
.
set
(
this
.
state
,
id
,
resolved
)
update
:
(
i
d
,
resolved
)
->
this
.
state
[
id
]
=
resolved
delete
:
(
id
)
->
Vue
.
delete
(
this
.
state
,
id
)
updateAll
:
(
state
)
->
for
id
,
resolved
of
this
.
state
this
.
update
(
id
,
state
)
if
resolved
isnt
state
getAllForState
:
(
state
)
->
ids
=
[]
for
id
,
resolved
of
this
.
state
ids
.
push
(
id
)
if
resolved
is
state
ids
get
:
(
discussionId
,
noteI
d
)
->
this
.
state
[
discussionId
][
noteId
]
create
:
(
discussionId
,
noteI
d
,
resolved
)
->
unless
this
.
state
[
discussionId
]
?
Vue
.
set
(
this
.
state
,
discussionId
,
{})
Vue
.
set
(
this
.
state
[
discussionId
],
noteId
,
resolved
)
update
:
(
discussionId
,
noteId
,
resolved
)
->
this
.
state
[
discussionId
][
noteId
]
=
resolved
delete
:
(
discussionId
,
noteId
)
->
Vue
.
delete
(
this
.
state
[
discussionId
],
noteId
)
if
Object
.
keys
(
this
.
state
[
discussionId
]).
length
is
0
Vue
.
delete
(
this
.
state
,
discussionId
)
app/assets/javascripts/merge_request_tabs.js.coffee
View file @
c1fe066b
...
...
@@ -157,6 +157,11 @@ class @MergeRequestTabs
url
:
"
#{
source
}
.json"
+
@
_location
.
search
success
:
(
data
)
=>
$
(
'#diffs'
).
html
data
.
html
if
$
(
'resolve-btn, resolve-all'
).
length
and
DiffNotesApp
?
$
(
'resolve-btn, resolve-all'
).
each
->
DiffNotesApp
.
$compile
$
(
this
).
get
(
0
)
gl
.
utils
.
localTimeAgo
(
$
(
'.js-timeago'
,
'div#diffs'
))
$
(
'#diffs .js-syntax-highlight'
).
syntaxHighlight
()
$
(
'#diffs .diff-file'
).
singleFileDiff
()
...
...
app/assets/javascripts/notes.js.coffee
View file @
c1fe066b
...
...
@@ -271,8 +271,8 @@ class @Notes
# append new note to all matching discussions
discussionContainer
.
append
note_html
if
$
(
'resolve-btn'
).
length
and
DiffNotesApp
?
$
(
'resolve-btn'
).
each
->
if
$
(
'resolve-btn
, resolve-all
'
).
length
and
DiffNotesApp
?
$
(
'resolve-btn
, resolve-all
'
).
each
->
DiffNotesApp
.
$compile
$
(
this
).
get
(
0
)
gl
.
utils
.
localTimeAgo
(
$
(
'.js-timeago'
,
note_html
),
false
)
...
...
@@ -507,10 +507,10 @@ class @Notes
replyToDiscussionNote
:
(
e
)
=>
form
=
@
formClone
.
clone
()
replyLink
=
$
(
e
.
target
).
closest
(
".js-discussion-reply-button"
)
replyLink
.
hide
()
# insert the form after the button
replyLink
.
after
form
replyLink
.
closest
(
'.discussion-reply-holder'
)
.
hide
()
.
after
form
# show the form
@
setupDiscussionNoteForm
(
replyLink
,
form
)
...
...
@@ -606,7 +606,9 @@ class @Notes
form
.
find
(
".js-note-text"
).
data
(
"autosave"
).
reset
()
# show the reply button (will only work for replies)
form
.
prev
(
".js-discussion-reply-button"
).
show
()
form
.
prev
(
'.discussion-reply-holder'
)
.
show
()
if
row
.
is
(
".js-temp-notes-holder"
)
# remove temporary row for diff lines
row
.
remove
()
...
...
app/assets/stylesheets/pages/note_form.scss
View file @
c1fe066b
...
...
@@ -156,6 +156,27 @@
.discussion-reply-holder
{
background-color
:
$white-light
;
padding
:
10px
16px
;
.btn-group-justified
{
table-layout
:
auto
;
}
.btn-group
:first-child
{
width
:
100%
;
}
.discussion-with-resolve-btn
{
.btn-group
:first-child
.btn
{
border-top-right-radius
:
0
;
border-bottom-right-radius
:
0
;
}
.btn-group
:last-child
.btn
{
margin-left
:
-1px
;
border-top-left-radius
:
0
;
border-bottom-left-radius
:
0
;
}
}
}
}
...
...
app/helpers/notes_helper.rb
View file @
c1fe066b
...
...
@@ -81,10 +81,8 @@ module NotesHelper
data
=
discussion
.
reply_attributes
.
merge
(
line_type:
line_type
)
content_tag
(
:div
,
class:
"discussion-reply-holder"
)
do
button_tag
'Reply...'
,
class:
'btn btn-text-field js-discussion-reply-button'
,
data:
data
,
title:
'Add a reply'
end
button_tag
'Reply...'
,
class:
'btn btn-text-field js-discussion-reply-button'
,
data:
data
,
title:
'Add a reply'
end
def
note_max_access_for_user
(
note
)
...
...
app/views/discussions/_diff_discussion.html.haml
View file @
c1fe066b
...
...
@@ -3,4 +3,10 @@
%td
.notes_content
%ul
.notes
{
data:
{
discussion_id:
discussion
.
id
}
}
=
render
partial:
"projects/notes/note"
,
collection:
discussion
.
notes
,
as: :note
=
link_to_reply_discussion
(
discussion
)
.discussion-reply-holder
.btn-group-justified.discussion-with-resolve-btn
{
role:
"group"
}
.btn-group
{
role:
"group"
}
=
link_to_reply_discussion
(
note
)
.btn-group
{
role:
"group"
}
=
render
"projects/notes/discussions/resolve_all"
,
note:
note
app/views/discussions/_parallel_diff_discussion.html.haml
View file @
c1fe066b
...
...
@@ -5,7 +5,12 @@
%ul
.notes
{
data:
{
discussion_id:
discussion_left
.
id
}
}
=
render
partial:
"projects/notes/note"
,
collection:
discussion_left
.
notes
,
as: :note
=
link_to_reply_discussion
(
discussion_left
,
'old'
)
.discussion-reply-holder
.btn-group-justified.discussion-with-resolve-btn
{
role:
"group"
}
.btn-group
{
role:
"group"
}
=
link_to_reply_discussion
(
note_left
,
'old'
)
.btn-group
{
role:
"group"
}
=
render
"projects/notes/discussions/resolve_all"
,
note:
note_left
-
else
%td
.notes_line.old
=
""
%td
.notes_content.parallel.old
=
""
...
...
@@ -16,7 +21,12 @@
%ul
.notes
{
data:
{
discussion_id:
discussion_right
.
id
}
}
=
render
partial:
"projects/notes/note"
,
collection:
discussion_right
.
notes
,
as: :note
=
link_to_reply_discussion
(
discussion_right
,
'new'
)
.discussion-reply-holder
.btn-group-justified.discussion-with-resolve-btn
{
role:
"group"
}
.btn-group
{
role:
"group"
}
=
link_to_reply_discussion
(
note_right
,
'new'
)
.btn-group
{
role:
"group"
}
=
render
"projects/notes/discussions/resolve_all"
,
note:
note_right
-
else
%td
.notes_line.new
=
""
%td
.notes_content.parallel.new
=
""
app/views/projects/merge_requests/_show.html.haml
View file @
c1fe066b
...
...
@@ -45,14 +45,11 @@
=
link_to
"command line"
,
"#modal_merge_info"
,
class:
"how_to_merge_link vlink"
,
title:
"How To Merge"
,
"data-toggle"
=>
"modal"
-
if
current_user
#resolve-
all
-app
{
"v-cloak"
=>
true
}
%resolve-
all
{
":namespace"
=>
"'#{@project.namespace.path}/#{@project.path}'"
,
"inline-template"
=>
true
}
#resolve-
count
-app
{
"v-cloak"
=>
true
}
%resolve-
count
{
"inline-template"
=>
true
}
.line-resolve-all
{
"v-show"
=>
"commentsCount > 0"
}
%button
.btn.btn-gray
{
type:
"button"
,
"aria-label"
=>
"Resolve all"
,
"@click"
=>
"updateAll"
,
":disabled"
=>
"loading"
}
=
icon
(
"spinner spin"
,
"v-show"
=>
"loading"
)
{{ buttonText }}
%span
.line-resolve-text
{{ resolved }}/{{ commentsCount }}
comment
s resolved
{{ resolved }}/{{ commentsCount }}
discussion
s resolved
-
if
@commits_count
.
nonzero?
%ul
.merge-request-tabs.nav-links.no-top.no-bottom
...
...
@@ -74,7 +71,7 @@
Changes
%span
.badge
=
@merge_request
.
diff_size
.tab-content
.tab-content
#diff-comments-app
#notes
.notes.tab-pane.voting_notes
.content-block.content-block-small.oneline-block
=
render
'award_emoji/awards_block'
,
awardable:
@merge_request
,
inline:
true
...
...
app/views/projects/notes/_note.html.haml
View file @
c1fe066b
...
...
@@ -21,7 +21,7 @@
-
if
access
and
not
note
.
system
%span
.note-role.hidden-xs
=
access
-
if
!
note
.
system
&&
current_user
%resolve-btn
{
":namespace"
=>
"'#{note.project.namespace.path}/#{note.project.path}'"
,
":note-id"
=>
note
.
id
,
":resolved"
=>
"false"
,
"inline-template"
=>
true
,
"v-ref:note_#{note.id}"
=>
true
}
%resolve-btn
{
":namespace"
=>
"'#{note.project.namespace.path}/#{note.project.path}'"
,
":
discussion-id"
=>
"'#{note.discussion_id}'"
,
":
note-id"
=>
note
.
id
,
":resolved"
=>
"false"
,
"inline-template"
=>
true
,
"v-ref:note_#{note.id}"
=>
true
}
.note-action-button
=
icon
(
"spin spinner"
,
"v-show"
=>
"loading"
)
%button
.line-resolve-btn
{
type:
"button"
,
":class"
=>
"{ 'is-active': isResolved }"
,
":aria-label"
=>
"buttonText"
,
"@click"
=>
"resolve"
,
":title"
=>
"buttonText"
,
"v-show"
=>
"!loading"
,
"v-el:button"
=>
true
}
...
...
app/views/projects/notes/discussions/_resolve_all.html.haml
0 → 100644
View file @
c1fe066b
%resolve-all
{
":namespace"
=>
"'#{note.project.namespace.path}/#{note.project.path}'"
,
":discussion-id"
=>
"'#{note.discussion_id}'"
,
"inline-template"
=>
true
,
"v-cloak"
=>
true
}
%button
.btn.btn-success
{
type:
"button"
,
"@click"
=>
"resolve"
,
":disabled"
=>
"loading"
}
=
icon
(
"spinner spin"
,
"v-show"
=>
"loading"
)
{{ buttonText }}
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