Commit 29d57486 authored by Douwe Maan's avatar Douwe Maan

Display new diff notes and allow creation through the web interface

parent 521a0a20
......@@ -240,12 +240,16 @@ class @Notes
@note_ids.push(note.id)
form = $("#new-discussion-note-form-#{note.discussion_id}")
if note.original_discussion_id? and form.length is 0
form = $("#new-discussion-note-form-#{note.original_discussion_id}")
row = form.closest("tr")
note_html = $(note.html)
note_html.syntaxHighlight()
# is this the first note of discussion?
discussionContainer = $(".notes[data-discussion-id='" + note.discussion_id + "']")
if note.original_discussion_id? and discussionContainer.length is 0
discussionContainer = $(".notes[data-discussion-id='" + note.original_discussion_id + "']")
if discussionContainer.length is 0
# insert the note and the reply button after the temp row
row.after note.discussion_html
......@@ -318,6 +322,7 @@ class @Notes
form.addClass "js-main-target-form"
form.find("#note_line_code").remove()
form.find("#note_position").remove()
form.find("#note_type").remove()
###
......@@ -335,10 +340,12 @@ class @Notes
new Autosave textarea, [
"Note"
form.find("#note_commit_id").val()
form.find("#note_line_code").val()
form.find("#note_noteable_type").val()
form.find("#note_noteable_id").val()
form.find("#note_commit_id").val()
form.find("#note_type").val()
form.find("#note_line_code").val()
form.find("#note_position").val()
]
###
......@@ -512,10 +519,12 @@ class @Notes
setupDiscussionNoteForm: (dataHolder, form) =>
# setup note target
form.attr 'id', "new-discussion-note-form-#{dataHolder.data("discussionId")}"
form.attr "data-line-code", dataHolder.data("lineCode")
form.find("#note_type").val dataHolder.data("noteType")
form.find("#line_type").val dataHolder.data("lineType")
form.find("#note_commit_id").val dataHolder.data("commitId")
form.find("#note_line_code").val dataHolder.data("lineCode")
form.find("#note_position").val dataHolder.attr("data-position")
form.find("#note_noteable_type").val dataHolder.data("noteableType")
form.find("#note_noteable_id").val dataHolder.data("noteableId")
form.find('.js-note-discard')
......
......@@ -434,13 +434,3 @@
}
}
}
.discussion {
.diff-content {
.diff-line-num {
&:before {
content: attr(data-linenumber);
}
}
}
}
......@@ -128,7 +128,7 @@ class Projects::NotesController < Projects::ApplicationController
elsif note.valid?
Banzai::NoteRenderer.render([note], @project, current_user)
{
attrs = {
valid: true,
id: note.id,
discussion_id: note.discussion_id,
......@@ -138,6 +138,23 @@ class Projects::NotesController < Projects::ApplicationController
discussion_html: note_to_discussion_html(note),
discussion_with_diff_html: note_to_discussion_with_diff_html(note)
}
# The discussion_id is used to add the comment to the correct discussion
# element on the merge request page. Among other things, the discussion_id
# contains the sha of head commit of the merge request.
# When new commits are pushed into the merge request after the initial
# load of the merge request page, the discussion elements will still have
# the old discussion_ids, with the old head commit sha. The new comment,
# however, will have the new discussion_id with the new commit sha.
# To ensure that these new comments will still end up in the correct
# discussion element, we also send the original discussion_id, with the
# old commit sha, along, and fall back on this value when no discussion
# element with the new discussion_id could be found.
if note.new_diff_note? && note.position != note.original_position
attrs[:original_discussion_id] = note.original_discussion_id
end
attrs
else
{
valid: false,
......@@ -154,7 +171,7 @@ class Projects::NotesController < Projects::ApplicationController
def note_params
params.require(:note).permit(
:note, :noteable, :noteable_id, :noteable_type, :project_id,
:attachment, :line_code, :commit_id, :type
:attachment, :line_code, :commit_id, :type, :position
)
end
......
......@@ -24,23 +24,55 @@ module NotesHelper
}.to_json
end
def link_to_new_diff_note(line_code, line_type = nil)
discussion_id = LegacyDiffNote.build_discussion_id(
@comments_target[:noteable_type],
@comments_target[:noteable_id] || @comments_target[:commit_id],
line_code
)
def link_to_new_diff_note(line_code, position, line_type = nil)
use_legacy_diff_note = @use_legacy_diff_notes
# If the controller doesn't force the use of legacy diff notes, we
# determine this on a line-by-line basis by seeing if there already exist
# active legacy diff notes at this line, in which case newly created notes
# will use the legacy technology as well.
# We do this because the discussion_id values of legacy and "new" diff
# notes, which are used to group notes on the merge request discussion tab,
# are incompatible.
# If we didn't, diff notes that would show for the same line on the changes
# tab, would show in different discussions on the discussion tab.
use_legacy_diff_note ||= begin
line_diff_notes = @grouped_diff_notes[line_code]
line_diff_notes && line_diff_notes.any?(&:legacy_diff_note?)
end
data = {
noteable_type: @comments_target[:noteable_type],
noteable_id: @comments_target[:noteable_id],
commit_id: @comments_target[:commit_id],
line_type: line_type,
line_code: line_code,
note_type: LegacyDiffNote.name,
discussion_id: discussion_id
line_code: line_code
}
if use_legacy_diff_note
discussion_id = LegacyDiffNote.build_discussion_id(
@comments_target[:noteable_type],
@comments_target[:noteable_id] || @comments_target[:commit_id],
line_code
)
data.merge!(
note_type: LegacyDiffNote.name,
discussion_id: discussion_id
)
else
discussion_id = DiffNote.build_discussion_id(
@comments_target[:noteable_type],
@comments_target[:noteable_id] || @comments_target[:commit_id],
position
)
data.merge!(
position: position.to_json,
note_type: DiffNote.name,
discussion_id: discussion_id
)
end
button_tag(class: 'btn add-diff-note js-add-diff-note-button',
data: data,
title: 'Add a comment to this line') do
......@@ -65,8 +97,10 @@ module NotesHelper
data.merge!(note.diff_attributes)
end
button_tag 'Reply...', class: 'btn btn-text-field js-discussion-reply-button',
data: data, title: 'Add a reply'
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
end
def note_max_access_for_user(note)
......
......@@ -29,8 +29,7 @@ module Emails
# used in notify layout
@target_url = @message.target_url
@project = Project.find(project_id)
@diff_notes_disabled = true
add_project_headers
headers['X-GitLab-Author'] = @message.author_username
......
- plain = local_assigns.fetch(:plain, false)
- line_code = diff_file.line_code(line)
- position = diff_file.position(line)
- type = line.type
%tr.line_holder{ id: line_code, class: type }
- case type
......@@ -10,18 +12,19 @@
%td.new_line.diff-line-num
%td.line_content.match= line.text
- else
%td.old_line.diff-line-num{ class: type, data: { linenumber: line.new_pos } }
%td.old_line.diff-line-num{ class: type, data: { linenumber: line.old_pos } }
- link_text = type == "new" ? "&nbsp;".html_safe : line.old_pos
- if defined?(plain) && plain
- if plain
= link_text
- else
= link_to "", "##{line_code}", id: line_code, data: { linenumber: link_text }
- if !@diff_notes_disabled && can?(current_user, :create_note, @project)
= link_to_new_diff_note(line_code)
- if !plain && !@diff_notes_disabled && can?(current_user, :create_note, @project)
= link_to_new_diff_note(line_code, position)
%td.new_line.diff-line-num{ class: type, data: { linenumber: line.new_pos } }
- link_text = type == "old" ? "&nbsp;".html_safe : line.new_pos
- if defined?(plain) && plain
- if plain
= link_text
- else
= link_to "", "##{line_code}", id: line_code, data: { linenumber: link_text }
%td.line_content{ class: ['noteable_line', type, line_code], data: { line_code: line_code } }= diff_line_content(line.text, type)
%td.line_content{ class: ['noteable_line', type, line_code], data: { line_code: line_code, position: position.to_json } }= diff_line_content(line.text, type)
......@@ -17,27 +17,25 @@
%td.old_line.diff-line-num{id: left[:line_code], class: "#{left[:type]} #{'empty-cell' if !left[:number]}"}
= link_to raw(left[:number]), "##{left[:line_code]}", id: left[:line_code]
- if !@diff_notes_disabled && can?(current_user, :create_note, @project)
= link_to_new_diff_note(left[:line_code], 'old')
%td.line_content{class: "parallel noteable_line #{left[:type]} #{left[:line_code]} #{'empty-cell' if left[:text].empty?}", data: { line_code: left[:line_code] }}= diff_line_content(left[:text])
= link_to_new_diff_note(left[:line_code], left[:position], 'old')
%td.line_content{class: "parallel noteable_line #{left[:type]} #{left[:line_code]} #{'empty-cell' if left[:text].empty?}", data: { line_code: left[:line_code], position: left[:position].to_json }}= diff_line_content(left[:text])
- if right[:type] == 'new'
- new_line_class = 'new'
- new_line_code = right[:line_code]
- new_position = right[:position]
- else
- new_line_class = nil
- new_line_code = left[:line_code]
- new_position = left[:position]
%td.new_line.diff-line-num{id: new_line_code, class: "#{new_line_class} #{'empty-cell' if !right[:number]}", data: { linenumber: right[:number] }}
= link_to raw(right[:number]), "##{new_line_code}", id: new_line_code
- if !@diff_notes_disabled && can?(current_user, :create_note, @project)
= link_to_new_diff_note(new_line_code, 'new')
%td.line_content.parallel{class: "noteable_line #{new_line_class} #{new_line_code} #{'empty-cell' if right[:text].empty?}", data: { line_code: new_line_code }}= diff_line_content(right[:text])
= link_to_new_diff_note(new_line_code, new_position, 'new')
%td.line_content.parallel{class: "noteable_line #{new_line_class} #{new_line_code} #{'empty-cell' if right[:text].empty?}", data: { line_code: new_line_code, position: new_position.to_json }}= diff_line_content(right[:text])
- unless @diff_notes_disabled
- notes_left, notes_right = organize_comments(left, right)
- if notes_left.present? || notes_right.present?
= render "projects/notes/diff_notes_with_reply_parallel", notes_left: notes_left, notes_right: notes_right
- if diff_file.diff.diff.blank? && diff_file.mode_changed?
.file-mode-changed
File mode changed
......@@ -4,22 +4,17 @@
%a.show-suppressed-diff.js-show-suppressed-diff Changes suppressed. Click to show.
%table.text-file.code.js-syntax-highlight{ class: too_big ? 'hide' : '' }
- last_line = 0
- diff_file.highlighted_diff_lines.each_with_index do |line, index|
- line_code = generate_line_code(diff_file.file_path, line)
- diff_file.highlighted_diff_lines.each do |line|
- last_line = line.new_pos
= render "projects/diffs/line", {line: line, diff_file: diff_file, line_code: line_code}
= render "projects/diffs/line", line: line, diff_file: diff_file
- unless @diff_notes_disabled
- diff_notes = @grouped_diff_notes[line_code]
- line_code = diff_file.line_code(line)
- diff_notes = @grouped_diff_notes[line_code] if line_code
- if diff_notes
= render "projects/notes/diff_notes_with_reply", notes: diff_notes
- if last_line > 0
= render "projects/diffs/match_line", { line: "",
line_old: last_line, line_new: last_line, bottom: true, new_file: diff_file.new_file }
- if diff_file.diff.blank? && diff_file.mode_changed?
.file-mode-changed
File mode changed
......@@ -7,6 +7,7 @@
= f.hidden_field :noteable_id
= f.hidden_field :noteable_type
= f.hidden_field :type
= f.hidden_field :position
= render layout: 'projects/md_preview', locals: { preview_class: "md-preview", referenced_users: true } do
= render 'projects/zen', f: f, attr: :note, classes: 'note-textarea js-note-text', placeholder: "Write a comment or drag your files here..."
......
......@@ -11,17 +11,7 @@
.diff-content.code.js-syntax-highlight
%table
- note.truncated_diff_lines.each do |line|
- type = line.type
- line_code = diff_file.line_code(line)
%tr.line_holder{ id: line_code, class: "#{type}" }
- if type == "match"
%td.old_line.diff-line-num= "..."
%td.new_line.diff-line-num= "..."
%td.line_content.match= line.text
- else
%td.old_line.diff-line-num{ data: { linenumber: type == "new" ? "&nbsp;".html_safe : line.old_pos } }
%td.new_line.diff-line-num{ data: { linenumber: type == "old" ? "&nbsp;".html_safe : line.new_pos } }
%td.line_content{ class: ['noteable_line', type, line_code], line_code: line_code }= diff_line_content(line.text, type)
= render "projects/diffs/line", line: line, diff_file: diff_file, plain: true
- if note.for_line?(line)
= render "projects/notes/diff_notes_with_reply", notes: discussion_notes
- if note.for_line?(line)
= render "projects/notes/diff_notes_with_reply", notes: discussion_notes
......@@ -23,7 +23,7 @@ module SharedDiffNote
page.within(diff_file_selector) do
click_diff_line(sample_commit.line_code)
page.within("form[id$='#{sample_commit.line_code}-true']") do
page.within("form[data-line-code='#{sample_commit.line_code}']") do
fill_in "note[note]", with: "Typo, please fix"
find(".js-comment-button").trigger("click")
sleep 0.05
......@@ -33,7 +33,7 @@ module SharedDiffNote
step 'I leave a diff comment in a parallel view on the left side like "Old comment"' do
click_parallel_diff_line(sample_commit.line_code, 'old')
page.within("#{diff_file_selector} form[id$='#{sample_commit.line_code}-true']") do
page.within("#{diff_file_selector} form[data-line-code='#{sample_commit.line_code}']") do
fill_in "note[note]", with: "Old comment"
find(".js-comment-button").trigger("click")
end
......@@ -41,7 +41,7 @@ module SharedDiffNote
step 'I leave a diff comment in a parallel view on the right side like "New comment"' do
click_parallel_diff_line(sample_commit.line_code, 'new')
page.within("#{diff_file_selector} form[id$='#{sample_commit.line_code}-true']") do
page.within("#{diff_file_selector} form[data-line-code='#{sample_commit.line_code}']") do
fill_in "note[note]", with: "New comment"
find(".js-comment-button").trigger("click")
end
......@@ -51,7 +51,7 @@ module SharedDiffNote
page.within(diff_file_selector) do
click_diff_line(sample_commit.line_code)
page.within("form[id$='#{sample_commit.line_code}-true']") do
page.within("form[data-line-code='#{sample_commit.line_code}']") do
fill_in "note[note]", with: "Should fix it :smile:"
find('.js-md-preview-button').click
end
......@@ -62,7 +62,7 @@ module SharedDiffNote
page.within(diff_file_selector) do
click_diff_line(sample_commit.del_line_code)
page.within("form[id$='#{sample_commit.del_line_code}-true']") do
page.within("form[data-line-code='#{sample_commit.del_line_code}']") do
fill_in "note[note]", with: "DRY this up"
find('.js-md-preview-button').click
end
......@@ -91,7 +91,7 @@ module SharedDiffNote
page.within(diff_file_selector) do
click_diff_line(sample_commit.line_code)
page.within("form[id$='#{sample_commit.line_code}-true']") do
page.within("form[data-line-code='#{sample_commit.line_code}']") do
fill_in 'note[note]', with: ':smile:'
click_button('Comment')
end
......
......@@ -18,6 +18,7 @@ module Gitlab
line_code = diff_file.line_code(line)
line_new = line.new_pos
line_old = line.old_pos
position = diff_file.position(line)
next_line = diff_file.next_line(line.index)
......@@ -26,6 +27,7 @@ module Gitlab
full_next_line = next_line.text
next_line_code = diff_file.line_code(next_line)
next_type = next_line.type
next_position = diff_file.position(next_line)
end
case type
......@@ -37,12 +39,14 @@ module Gitlab
number: line_old,
text: full_line,
line_code: line_code,
position: position
},
right: {
type: type,
number: line_new,
text: full_line,
line_code: line_code
line_code: line_code,
position: position
}
}
when 'old'
......@@ -55,12 +59,14 @@ module Gitlab
number: line_old,
text: full_line,
line_code: line_code,
position: position
},
right: {
type: next_type,
number: line_new,
text: full_next_line,
line_code: next_line_code,
position: next_position,
}
}
skip_next = true
......@@ -73,12 +79,14 @@ module Gitlab
number: line_old,
text: full_line,
line_code: line_code,
position: position
},
right: {
type: next_type,
number: nil,
text: "",
line_code: nil
line_code: nil,
position: nil
}
}
end
......@@ -95,12 +103,14 @@ module Gitlab
number: nil,
text: "",
line_code: line_code,
position: position
},
right: {
type: type,
number: line_new,
text: full_line,
line_code: line_code
line_code: line_code,
position: position
}
}
end
......
......@@ -166,12 +166,14 @@ describe 'Comments', feature: true do
click_diff_line
is_expected.
to have_css("tr[id='#{line_code}'] + .js-temp-notes-holder form",
to have_css("form[data-line-code='#{line_code}']",
count: 1)
end
it 'should be removed when canceled' do
page.within(".diff-file form[id$='#{line_code}-true']") do
is_expected.to have_css('.js-temp-notes-holder')
page.within("form[data-line-code='#{line_code}']") do
find('.js-close-discussion-note-form').trigger('click')
end
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment