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
Léo-Paul Géneau
gitlab-ce
Commits
cc656a11
Commit
cc656a11
authored
Apr 06, 2017
by
Douwe Maan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor resolvability checks based on type
parent
64c1735c
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
107 additions
and
39 deletions
+107
-39
app/models/concerns/issuable.rb
app/models/concerns/issuable.rb
+0
-11
app/models/concerns/noteable.rb
app/models/concerns/noteable.rb
+25
-0
app/models/concerns/resolvable_discussion.rb
app/models/concerns/resolvable_discussion.rb
+2
-5
app/models/concerns/resolvable_note.rb
app/models/concerns/resolvable_note.rb
+7
-5
app/models/diff_discussion.rb
app/models/diff_discussion.rb
+6
-0
app/models/diff_note.rb
app/models/diff_note.rb
+2
-0
app/models/discussion.rb
app/models/discussion.rb
+6
-0
app/models/discussion_note.rb
app/models/discussion_note.rb
+4
-2
app/models/individual_note_discussion.rb
app/models/individual_note_discussion.rb
+4
-2
app/models/legacy_diff_discussion.rb
app/models/legacy_diff_discussion.rb
+5
-2
app/models/legacy_diff_note.rb
app/models/legacy_diff_note.rb
+3
-0
app/models/note.rb
app/models/note.rb
+4
-5
app/models/out_of_context_discussion.rb
app/models/out_of_context_discussion.rb
+5
-3
app/services/issues/build_service.rb
app/services/issues/build_service.rb
+5
-3
app/views/projects/notes/_comment_button.html.haml
app/views/projects/notes/_comment_button.html.haml
+28
-0
app/views/projects/notes/_form.html.haml
app/views/projects/notes/_form.html.haml
+1
-1
No files found.
app/models/concerns/issuable.rb
View file @
cc656a11
...
@@ -292,17 +292,6 @@ module Issuable
...
@@ -292,17 +292,6 @@ module Issuable
self
.
class
.
to_ability_name
self
.
class
.
to_ability_name
end
end
# Convert this Issuable class name to a format usable by notifications.
#
# Examples:
#
# issuable.class # => MergeRequest
# issuable.human_class_name # => "merge request"
def
human_class_name
@human_class_name
||=
self
.
class
.
name
.
titleize
.
downcase
end
# Returns a Hash of attributes to be used for Twitter card metadata
# Returns a Hash of attributes to be used for Twitter card metadata
def
card_attributes
def
card_attributes
{
{
...
...
app/models/concerns/noteable.rb
View file @
cc656a11
module
Noteable
module
Noteable
# Names of all implementers of `Noteable` that support resolvable notes.
RESOLVABLE_TYPES
=
%w(MergeRequest)
.
freeze
def
base_class_name
self
.
class
.
base_class
.
name
end
# Convert this Noteable class name to a format usable by notifications.
#
# Examples:
#
# noteable.class # => MergeRequest
# noteable.human_class_name # => "merge request"
def
human_class_name
@human_class_name
||=
base_class_name
.
titleize
.
downcase
end
def
supports_resolvable_notes?
RESOLVABLE_TYPES
.
include?
(
base_class_name
)
end
def
supports_discussions?
DiscussionNote
::
NOTEABLE_TYPES
.
include?
(
base_class_name
)
end
def
discussion_notes
def
discussion_notes
notes
notes
end
end
...
...
app/models/concerns/resolvable_discussion.rb
View file @
cc656a11
...
@@ -20,6 +20,8 @@ module ResolvableDiscussion
...
@@ -20,6 +20,8 @@ module ResolvableDiscussion
:last_note
:last_note
)
)
delegate
:potentially_resolvable?
,
to: :first_note
delegate
:resolved_at
,
delegate
:resolved_at
,
:resolved_by
,
:resolved_by
,
...
@@ -27,11 +29,6 @@ module ResolvableDiscussion
...
@@ -27,11 +29,6 @@ module ResolvableDiscussion
allow_nil:
true
allow_nil:
true
end
end
# Keep this method in sync with the `potentially_resolvable` scope on `ResolvableNote`
def
potentially_resolvable?
for_merge_request?
end
def
resolvable?
def
resolvable?
return
@resolvable
if
@resolvable
.
present?
return
@resolvable
if
@resolvable
.
present?
...
...
app/models/concerns/resolvable_note.rb
View file @
cc656a11
module
ResolvableNote
module
ResolvableNote
extend
ActiveSupport
::
Concern
extend
ActiveSupport
::
Concern
# Names of all subclasses of `Note` that can be resolvable.
RESOLVABLE_TYPES
=
%w(DiffNote DiscussionNote)
.
freeze
RESOLVABLE_TYPES
=
%w(DiffNote DiscussionNote)
.
freeze
included
do
included
do
...
@@ -8,10 +9,8 @@ module ResolvableNote
...
@@ -8,10 +9,8 @@ module ResolvableNote
validates
:resolved_by
,
presence:
true
,
if: :resolved?
validates
:resolved_by
,
presence:
true
,
if: :resolved?
# Keep this scope in sync with the logic in `#potentially_resolvable?` in subclasses of `Discussion` that are resolvable.
# Keep this scope in sync with `#potentially_resolvable?`
# `RESOLVABLE_TYPES` should include names of all subclasses that are resolvable (where the method can return true), and
scope
:potentially_resolvable
,
->
{
where
(
type:
RESOLVABLE_TYPES
).
where
(
noteable_type:
Noteable
::
RESOLVABLE_TYPES
)
}
# the scope should also match the criteria `ResolvableDiscussion#potentially_resolvable?` puts on resolvability.
scope
:potentially_resolvable
,
->
{
where
(
type:
RESOLVABLE_TYPES
).
where
(
noteable_type:
'MergeRequest'
)
}
# Keep this scope in sync with `#resolvable?`
# Keep this scope in sync with `#resolvable?`
scope
:resolvable
,
->
{
potentially_resolvable
.
user
}
scope
:resolvable
,
->
{
potentially_resolvable
.
user
}
...
@@ -31,7 +30,10 @@ module ResolvableNote
...
@@ -31,7 +30,10 @@ module ResolvableNote
end
end
end
end
delegate
:potentially_resolvable?
,
to: :to_discussion
# Keep this method in sync with the `potentially_resolvable` scope
def
potentially_resolvable?
RESOLVABLE_TYPES
.
include?
(
self
.
class
.
name
)
&&
noteable
.
supports_resolvable_notes?
end
# Keep this method in sync with the `resolvable` scope
# Keep this method in sync with the `resolvable` scope
def
resolvable?
def
resolvable?
...
...
app/models/diff_discussion.rb
View file @
cc656a11
# A discussion on merge request or commit diffs consisting of `DiffNote` notes.
# A discussion on merge request or commit diffs consisting of `DiffNote` notes.
#
# A discussion of this type can be resolvable.
class
DiffDiscussion
<
Discussion
class
DiffDiscussion
<
Discussion
include
DiscussionOnDiff
include
DiscussionOnDiff
def
self
.
note_class
DiffNote
end
delegate
:position
,
delegate
:position
,
:original_position
,
:original_position
,
...
...
app/models/diff_note.rb
View file @
cc656a11
# A note on merge request or commit diffs
# A note on merge request or commit diffs
#
# A note of this type can be resolvable.
class
DiffNote
<
Note
class
DiffNote
<
Note
include
NoteOnDiff
include
NoteOnDiff
...
...
app/models/discussion.rb
View file @
cc656a11
# A non-diff discussion on an issue, merge request, commit, or snippet, consisting of `DiscussionNote` notes.
# A non-diff discussion on an issue, merge request, commit, or snippet, consisting of `DiscussionNote` notes.
#
# A discussion of this type can be resolvable.
class
Discussion
class
Discussion
include
ResolvableDiscussion
include
ResolvableDiscussion
...
@@ -54,6 +56,10 @@ class Discussion
...
@@ -54,6 +56,10 @@ class Discussion
nil
nil
end
end
def
self
.
note_class
DiscussionNote
end
def
initialize
(
notes
,
noteable
=
nil
)
def
initialize
(
notes
,
noteable
=
nil
)
@notes
=
notes
@notes
=
notes
@noteable
=
noteable
@noteable
=
noteable
...
...
app/models/discussion_note.rb
View file @
cc656a11
# A note in a non-diff discussion on an issue, merge request, commit, or snippet
# A note in a non-diff discussion on an issue, merge request, commit, or snippet.
#
# A note of this type can be resolvable.
class
DiscussionNote
<
Note
class
DiscussionNote
<
Note
# Names of all implementers of `Noteable` that support discussions.
NOTEABLE_TYPES
=
%w(MergeRequest Issue Commit Snippet)
.
freeze
NOTEABLE_TYPES
=
%w(MergeRequest Issue Commit Snippet)
.
freeze
RESOLVABLE_TYPES
=
%w(MergeRequest)
.
freeze
validates
:noteable_type
,
inclusion:
{
in:
NOTEABLE_TYPES
}
validates
:noteable_type
,
inclusion:
{
in:
NOTEABLE_TYPES
}
...
...
app/models/individual_note_discussion.rb
View file @
cc656a11
# A discussion to wrap a single `Note` note on the root of an issue, merge request,
# A discussion to wrap a single `Note` note on the root of an issue, merge request,
# commit, or snippet, that is not displayed as a discussion.
# commit, or snippet, that is not displayed as a discussion.
#
# A discussion of this type is never resolvable.
class
IndividualNoteDiscussion
<
Discussion
class
IndividualNoteDiscussion
<
Discussion
def
potentially_resolvable?
def
self
.
note_class
fals
e
Not
e
end
end
def
individual_note?
def
individual_note?
...
...
app/models/legacy_diff_discussion.rb
View file @
cc656a11
# A discussion on merge request or commit diffs consisting of `LegacyDiffNote` notes.
# A discussion on merge request or commit diffs consisting of `LegacyDiffNote` notes.
#
# All new diff discussions are of the type `DiffDiscussion`, but any diff discussions created
# All new diff discussions are of the type `DiffDiscussion`, but any diff discussions created
# before the introduction of the new implementation still use `LegacyDiffDiscussion`.
# before the introduction of the new implementation still use `LegacyDiffDiscussion`.
#
# A discussion of this type is never resolvable.
class
LegacyDiffDiscussion
<
Discussion
class
LegacyDiffDiscussion
<
Discussion
include
DiscussionOnDiff
include
DiscussionOnDiff
...
@@ -8,8 +11,8 @@ class LegacyDiffDiscussion < Discussion
...
@@ -8,8 +11,8 @@ class LegacyDiffDiscussion < Discussion
true
true
end
end
def
potentially_resolvable?
def
self
.
note_class
fals
e
LegacyDiffNot
e
end
end
def
collapsed?
def
collapsed?
...
...
app/models/legacy_diff_note.rb
View file @
cc656a11
# A note on merge request or commit diffs, using the legacy implementation.
# A note on merge request or commit diffs, using the legacy implementation.
#
# All new diff notes are of the type `DiffNote`, but any diff notes created
# All new diff notes are of the type `DiffNote`, but any diff notes created
# before the introduction of the new implementation still use `LegacyDiffNote`.
# before the introduction of the new implementation still use `LegacyDiffNote`.
#
# A note of this type is never resolvable.
class
LegacyDiffNote
<
Note
class
LegacyDiffNote
<
Note
include
NoteOnDiff
include
NoteOnDiff
...
...
app/models/note.rb
View file @
cc656a11
# A note on the root of an issue, merge request, commit, or snippet.
#
# A note of this type is never resolvable.
class
Note
<
ActiveRecord
::
Base
class
Note
<
ActiveRecord
::
Base
extend
ActiveModel
::
Naming
extend
ActiveModel
::
Naming
include
Gitlab
::
CurrentSettings
include
Gitlab
::
CurrentSettings
...
@@ -225,11 +228,7 @@ class Note < ActiveRecord::Base
...
@@ -225,11 +228,7 @@ class Note < ActiveRecord::Base
end
end
def
can_be_discussion_note?
def
can_be_discussion_note?
DiscussionNote
::
NOTEABLE_TYPES
.
include?
(
self
.
noteable_type
)
&&
!
part_of_discussion?
self
.
noteable
.
supports_discussions?
&&
!
part_of_discussion?
end
def
can_be_resolvable?
DiscussionNote
::
RESOLVABLE_TYPES
.
include?
(
self
.
noteable_type
)
end
end
def
discussion_class
(
noteable
=
nil
)
def
discussion_class
(
noteable
=
nil
)
...
...
app/models/out_of_context_discussion.rb
View file @
cc656a11
...
@@ -2,6 +2,8 @@
...
@@ -2,6 +2,8 @@
# contains that commit, they are displayed as if they were a discussion.
# contains that commit, they are displayed as if they were a discussion.
#
#
# This represents one of those discussions, consisting of `Note` notes.
# This represents one of those discussions, consisting of `Note` notes.
#
# A discussion of this type is never resolvable.
class
OutOfContextDiscussion
<
Discussion
class
OutOfContextDiscussion
<
Discussion
# Returns an array of discussion ID components
# Returns an array of discussion ID components
def
self
.
build_discussion_id
(
note
)
def
self
.
build_discussion_id
(
note
)
...
@@ -13,8 +15,8 @@ class OutOfContextDiscussion < Discussion
...
@@ -13,8 +15,8 @@ class OutOfContextDiscussion < Discussion
def
self
.
override_discussion_id
(
note
)
def
self
.
override_discussion_id
(
note
)
discussion_id
(
note
)
discussion_id
(
note
)
end
end
def
potentially_resolvable?
def
self
.
note_class
fals
e
Not
e
end
end
end
end
app/services/issues/build_service.rb
View file @
cc656a11
...
@@ -36,12 +36,14 @@ module Issues
...
@@ -36,12 +36,14 @@ module Issues
def
item_for_discussion
(
discussion
)
def
item_for_discussion
(
discussion
)
first_note_to_resolve
=
discussion
.
first_note_to_resolve
||
discussion
.
first_note
first_note_to_resolve
=
discussion
.
first_note_to_resolve
||
discussion
.
first_note
other_note_count
=
discussion
.
notes
.
size
-
1
note_url
=
Gitlab
::
UrlBuilder
.
build
(
first_note_to_resolve
)
is_very_first_note
=
first_note_to_resolve
==
discussion
.
first_note
is_very_first_note
=
first_note_to_resolve
==
discussion
.
first_note
action
=
is_very_first_note
?
"started"
:
"commented on"
action
=
is_very_first_note
?
"started"
:
"commented on"
note_url
=
Gitlab
::
UrlBuilder
.
build
(
first_note_to_resolve
)
other_note_count
=
discussion
.
notes
.
size
-
1
discussion_info
=
"- [ ]
#{
first_note_to_resolve
.
author
.
to_reference
}
#{
action
}
a [discussion](
#{
note_url
}
): "
discussion_info
=
"- [ ]
#{
first_note_to_resolve
.
author
.
to_reference
}
#{
action
}
a [discussion](
#{
note_url
}
): "
discussion_info
<<
" (+
#{
other_note_count
}
#{
'comment'
.
pluralize
(
other_note_count
)
}
)"
if
other_note_count
>
0
discussion_info
<<
" (+
#{
other_note_count
}
#{
'comment'
.
pluralize
(
other_note_count
)
}
)"
if
other_note_count
>
0
...
...
app/views/projects/notes/_comment_
type_
button.html.haml
→
app/views/projects/notes/_comment_button.html.haml
View file @
cc656a11
-
noteable_
type
=
@note
.
noteable_typ
e
-
noteable_
name
=
@note
.
noteable
.
human_class_nam
e
.pull-left.btn-group.append-right-10.comment-type-dropdown.js-comment-type-dropdown
.pull-left.btn-group.append-right-10.comment-type-dropdown.js-comment-type-dropdown
%input
.btn.btn-nr.btn-create.comment-btn.js-comment-button.js-comment-submit-button
{
type:
'submit'
,
value:
'Comment'
}
%input
.btn.btn-nr.btn-create.comment-btn.js-comment-button.js-comment-submit-button
{
type:
'submit'
,
value:
'Comment'
}
-
if
@note
.
can_be_discussion_note?
-
if
@note
.
can_be_discussion_note?
=
button_tag
type:
'button'
,
class:
'btn btn-nr dropdown-toggle comment-btn js-note-new-discussion js-disable-on-submit'
,
data:
{
'dropdown-trigger'
=>
'#resolvable-comment-menu'
},
'aria-label'
=>
'Open comment type dropdown'
do
=
button_tag
type:
'button'
,
class:
'btn btn-nr dropdown-toggle comment-btn js-note-new-discussion js-disable-on-submit'
,
data:
{
'dropdown-trigger'
=>
'#resolvable-comment-menu'
},
'aria-label'
=>
'Open comment type dropdown'
do
=
icon
(
'caret-down'
)
=
icon
(
'caret-down'
)
%ul
#resolvable-comment-menu
.dropdown-menu
{
data:
{
dropdown:
true
}
}
%ul
#resolvable-comment-menu
.dropdown-menu
{
data:
{
dropdown:
true
}
}
%li
#comment
.droplab-item-selected
{
data:
{
value:
''
,
'button-text'
=>
'Comment'
,
'secondary-button-text'
=>
"Comment & close #{noteable_
type.titleize.downcas
e}"
}
}
%li
#comment
.droplab-item-selected
{
data:
{
value:
''
,
'button-text'
=>
'Comment'
,
'secondary-button-text'
=>
"Comment & close #{noteable_
nam
e}"
}
}
=
icon
(
'check'
)
=
icon
(
'check'
)
.description
.description
%strong
Comment
%strong
Comment
%p
=
"Add a general comment to this
#{
noteable_type
.
titleize
.
downcase
}
."
%p
Add a general comment to this
#{
noteable_name
}
.
%li
.divider
%li
.divider
-
if
@note
.
can_be_resolvable?
%li
#discussion
{
data:
{
value:
'DiscussionNote'
,
'button-text'
=>
'Start discussion'
,
'secondary-button-text'
=>
"Start discussion & close #{noteable_type.titleize.downcase}"
}
}
%li
#discussion
{
data:
{
value:
'DiscussionNote'
,
'button-text'
=>
'Start discussion'
,
'secondary-button-text'
=>
"Start discussion & close #{noteable_name}"
}
}
=
icon
(
'check'
)
=
icon
(
'check'
)
.description
.description
%strong
Start discussion
%strong
Start discussion
%p
%p
Discuss a specific suggestion or question that needs to be resolved.
=
succeed
'.'
do
-
else
Discuss a specific suggestion or question
%li
#discussion
{
data:
{
value:
'DiscussionNote'
,
'button-text'
=>
'Start discussion'
,
'secondary-button-text'
=>
"Start discussion & close #{noteable_type.titleize.downcase}"
}
}
-
if
@note
.
noteable
.
supports_resolvable_notes?
=
icon
(
'check'
)
that needs to be resolved
.description
%strong
Start discussion
%p
Discuss a specific suggestion or question.
app/views/projects/notes/_form.html.haml
View file @
cc656a11
...
@@ -28,7 +28,7 @@
...
@@ -28,7 +28,7 @@
.error-alert
.error-alert
.note-form-actions.clearfix
.note-form-actions.clearfix
=
render
partial:
'projects/notes/comment_
type_button'
,
locals:
{
show_close_button:
true
}
=
render
partial:
'projects/notes/comment_
button'
=
yield
(
:note_actions
)
=
yield
(
:note_actions
)
...
...
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