-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Write new Notes coffee class to handle comments
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
- Loading branch information
1 parent
f7e7dc7
commit 923bd2e
Showing
1 changed file
with
397 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,397 @@ | ||
class Notes | ||
constructor: (notes_url, note_ids) -> | ||
@notes_url = notes_url | ||
@notes_url = gon.relative_url_root + @notes_url if gon.relative_url_root? | ||
@note_ids = note_ids | ||
@initRefresh() | ||
@setupMainTargetNoteForm() | ||
@cleanBinding() | ||
@addBinding() | ||
|
||
addBinding: -> | ||
# add note to UI after creation | ||
$(document).on "ajax:success", ".js-main-target-form", @addNote | ||
$(document).on "ajax:success", ".js-discussion-note-form", @addDiscussionNote | ||
|
||
# change note in UI after update | ||
$(document).on "ajax:success", "form.edit_note", @updateNote | ||
|
||
# Edit note link | ||
$(document).on "click", ".js-note-edit", @showEditForm | ||
$(document).on "click", ".note-edit-cancel", @cancelEdit | ||
|
||
# remove a note (in general) | ||
$(document).on "click", ".js-note-delete", @removeNote | ||
|
||
# delete note attachment | ||
$(document).on "click", ".js-note-attachment-delete", @removeAttachment | ||
|
||
# Preview button | ||
$(document).on "click", ".js-note-preview-button", @previewNote | ||
|
||
# reset main target form after submit | ||
$(document).on "ajax:complete", ".js-main-target-form", @resetMainTargetForm | ||
|
||
# attachment button | ||
$(document).on "click", ".js-choose-note-attachment-button", @chooseNoteAttachment | ||
|
||
# reply to diff/discussion notes | ||
$(document).on "click", ".js-discussion-reply-button", @replyToDiscussionNote | ||
|
||
# add diff note | ||
$(document).on "click", ".js-add-diff-note-button", @addDiffNote | ||
|
||
cleanBinding: -> | ||
$(document).off "ajax:success", ".js-main-target-form" | ||
$(document).off "ajax:success", ".js-discussion-note-form" | ||
$(document).off "ajax:success", "form.edit_note" | ||
$(document).off "click", ".js-note-edit" | ||
$(document).off "click", ".note-edit-cancel" | ||
$(document).off "click", ".js-note-delete" | ||
$(document).off "click", ".js-note-attachment-delete" | ||
$(document).off "click", ".js-note-preview-button" | ||
$(document).off "ajax:complete", ".js-main-target-form" | ||
$(document).off "click", ".js-choose-note-attachment-button" | ||
$(document).off "click", ".js-discussion-reply-button" | ||
$(document).off "click", ".js-add-diff-note-button" | ||
|
||
|
||
initRefresh: -> | ||
setInterval => | ||
@refresh() | ||
, 15000 | ||
|
||
refresh: -> | ||
@getContent() | ||
|
||
getContent: -> | ||
$.ajax | ||
url: @notes_url | ||
dataType: "json" | ||
success: (data) => | ||
notes = data.notes | ||
$.each notes, (i, note) => | ||
# render note if it not present in loaded list | ||
# or skip if rendered | ||
if $.inArray(note.id, @note_ids) == -1 | ||
@note_ids.push(note.id) | ||
@renderNote(note) | ||
|
||
|
||
### | ||
Render note in main comments area. | ||
Note: for rendering inline notes use renderDiscussionNote | ||
### | ||
renderNote: (note) -> | ||
$('ul.main-notes-list').append(note.html) | ||
|
||
### | ||
Render note in discussion area. | ||
Note: for rendering inline notes use renderDiscussionNote | ||
### | ||
renderDiscussionNote: (note) -> | ||
form = $("form[rel='" + note.discussion_id + "']") | ||
row = form.closest("tr") | ||
|
||
# is this the first note of discussion? | ||
if row.is(".js-temp-notes-holder") | ||
# insert the note and the reply button after the temp row | ||
row.after note.discussion_html | ||
|
||
# remove the note (will be added again below) | ||
row.next().find(".note").remove() | ||
|
||
# append new note to all matching discussions | ||
$(".notes[rel='" + note.discussion_id + "']").append note.html | ||
|
||
# cleanup after successfully creating a diff/discussion note | ||
@removeDiscussionNoteForm(form) | ||
|
||
### | ||
Shows the note preview. | ||
Lets the server render GFM into Html and displays it. | ||
Note: uses the Toggler behavior to toggle preview/edit views/buttons | ||
### | ||
previewNote: (e) -> | ||
e.preventDefault() | ||
form = $(this).closest("form") | ||
preview = form.find(".js-note-preview") | ||
noteText = form.find(".js-note-text").val() | ||
if noteText.trim().length is 0 | ||
preview.text "Nothing to preview." | ||
else | ||
preview.text "Loading..." | ||
$.post($(this).data("url"), | ||
note: noteText | ||
).success (previewData) -> | ||
preview.html previewData | ||
|
||
### | ||
Called in response the main target form has been successfully submitted. | ||
Removes any errors. | ||
Resets text and preview. | ||
Resets buttons. | ||
### | ||
resetMainTargetForm: -> | ||
form = $(".js-main-target-form") | ||
|
||
# remove validation errors | ||
form.find(".js-errors").remove() | ||
|
||
# reset text and preview | ||
previewContainer = form.find(".js-toggler-container.note_text_and_preview") | ||
previewContainer.removeClass "on" if previewContainer.is(".on") | ||
form.find(".js-note-text").val("").trigger "input" | ||
|
||
### | ||
Called when clicking the "Choose File" button. | ||
Opens the file selection dialog. | ||
### | ||
chooseNoteAttachment: -> | ||
form = $(this).closest("form") | ||
form.find(".js-note-attachment-input").click() | ||
|
||
### | ||
Shows the main form and does some setup on it. | ||
Sets some hidden fields in the form. | ||
### | ||
setupMainTargetNoteForm: -> | ||
|
||
# find the form | ||
form = $(".js-new-note-form") | ||
|
||
# insert the form after the button | ||
form.clone().replaceAll $(".js-main-target-form") | ||
form = form.prev("form") | ||
|
||
# show the form | ||
@setupNoteForm(form) | ||
|
||
# fix classes | ||
form.removeClass "js-new-note-form" | ||
form.addClass "js-main-target-form" | ||
|
||
# remove unnecessary fields and buttons | ||
form.find("#note_line_code").remove() | ||
form.find(".js-close-discussion-note-form").remove() | ||
|
||
### | ||
General note form setup. | ||
deactivates the submit button when text is empty | ||
hides the preview button when text is empty | ||
setup GFM auto complete | ||
show the form | ||
### | ||
setupNoteForm: (form) -> | ||
disableButtonIfEmptyField form.find(".js-note-text"), form.find(".js-comment-button") | ||
form.removeClass "js-new-note-form" | ||
|
||
# setup preview buttons | ||
form.find(".js-note-edit-button, .js-note-preview-button").tooltip placement: "left" | ||
previewButton = form.find(".js-note-preview-button") | ||
form.find(".js-note-text").on "input", -> | ||
if $(this).val().trim() isnt "" | ||
previewButton.removeClass("turn-off").addClass "turn-on" | ||
else | ||
previewButton.removeClass("turn-on").addClass "turn-off" | ||
|
||
|
||
# remove notify commit author checkbox for non-commit notes | ||
form.find(".js-notify-commit-author").remove() if form.find("#note_noteable_type").val() isnt "Commit" | ||
GitLab.GfmAutoComplete.setup() | ||
form.show() | ||
|
||
|
||
### | ||
Called in response to the new note form being submitted | ||
Adds new note to list. | ||
### | ||
addNote: (xhr, note, status) => | ||
@note_ids.push(note.id) | ||
@renderNote(note) | ||
|
||
### | ||
Called in response to the new note form being submitted | ||
Adds new note to list. | ||
### | ||
addDiscussionNote: (xhr, note, status) => | ||
@note_ids.push(note.id) | ||
@renderDiscussionNote(note) | ||
|
||
### | ||
Called in response to the edit note form being submitted | ||
Updates the current note field. | ||
### | ||
updateNote: (xhr, note, status) => | ||
note_li = $("#note_" + note.id) | ||
note_li.replaceWith(note.html) | ||
|
||
### | ||
Called in response to clicking the edit note link | ||
Replaces the note text with the note edit form | ||
Adds a hidden div with the original content of the note to fill the edit note form with | ||
if the user cancels | ||
### | ||
showEditForm: (e) -> | ||
e.preventDefault() | ||
note = $(this).closest(".note") | ||
note.find(".note-text").hide() | ||
|
||
# Show the attachment delete link | ||
note.find(".js-note-attachment-delete").show() | ||
GitLab.GfmAutoComplete.setup() | ||
form = note.find(".note-edit-form") | ||
form.show() | ||
form.find("textarea").focus() | ||
|
||
### | ||
Called in response to clicking the edit note link | ||
Hides edit form | ||
### | ||
cancelEdit: (e) -> | ||
e.preventDefault() | ||
note = $(this).closest(".note") | ||
note.find(".note-text").show() | ||
note.find(".js-note-attachment-delete").hide() | ||
note.find(".note-edit-form").hide() | ||
|
||
### | ||
Called in response to deleting a note of any kind. | ||
Removes the actual note from view. | ||
Removes the whole discussion if the last note is being removed. | ||
### | ||
removeNote: -> | ||
note = $(this).closest(".note") | ||
notes = note.closest(".notes") | ||
|
||
# check if this is the last note for this line | ||
if notes.find(".note").length is 1 | ||
|
||
# for discussions | ||
notes.closest(".discussion").remove() | ||
|
||
# for diff lines | ||
notes.closest("tr").remove() | ||
|
||
note.remove() | ||
|
||
### | ||
Called in response to clicking the delete attachment link | ||
Removes the attachment wrapper view, including image tag if it exists | ||
Resets the note editing form | ||
### | ||
removeAttachment: -> | ||
note = $(this).closest(".note") | ||
note.find(".note-attachment").remove() | ||
note.find(".note-text").show() | ||
note.find(".js-note-attachment-delete").hide() | ||
note.find(".note-edit-form").hide() | ||
|
||
### | ||
Called when clicking on the "reply" button for a diff line. | ||
Shows the note form below the notes. | ||
### | ||
replyToDiscussionNote: (e) => | ||
form = $(".js-new-note-form") | ||
replyLink = $(e.target) | ||
replyLink.hide() | ||
|
||
# insert the form after the button | ||
form.clone().insertAfter replyLink | ||
|
||
# show the form | ||
@setupDiscussionNoteForm(replyLink, replyLink.next("form")) | ||
|
||
### | ||
Shows the diff or discussion form and does some setup on it. | ||
Sets some hidden fields in the form. | ||
Note: dataHolder must have the "discussionId", "lineCode", "noteableType" | ||
and "noteableId" data attributes set. | ||
### | ||
setupDiscussionNoteForm: (dataHolder, form) => | ||
# setup note target | ||
form.attr "rel", dataHolder.data("discussionId") | ||
form.find("#note_commit_id").val dataHolder.data("commitId") | ||
form.find("#note_line_code").val dataHolder.data("lineCode") | ||
form.find("#note_noteable_type").val dataHolder.data("noteableType") | ||
form.find("#note_noteable_id").val dataHolder.data("noteableId") | ||
@setupNoteForm form | ||
form.find(".js-note-text").focus() | ||
form.addClass "js-discussion-note-form" | ||
|
||
### | ||
General note form setup. | ||
deactivates the submit button when text is empty | ||
hides the preview button when text is empty | ||
setup GFM auto complete | ||
show the form | ||
### | ||
setupNoteForm: (form) => | ||
disableButtonIfEmptyField form.find(".js-note-text"), form.find(".js-comment-button") | ||
form.removeClass "js-new-note-form" | ||
form.removeClass "js-new-note-form" | ||
GitLab.GfmAutoComplete.setup() | ||
form.show() | ||
|
||
### | ||
Called when clicking on the "add a comment" button on the side of a diff line. | ||
Inserts a temporary row for the form below the line. | ||
Sets up the form and shows it. | ||
### | ||
addDiffNote: (e) => | ||
e.preventDefault() | ||
link = e.target | ||
form = $(".js-new-note-form") | ||
row = $(link).closest("tr") | ||
nextRow = row.next() | ||
|
||
# does it already have notes? | ||
if nextRow.is(".notes_holder") | ||
$.proxy(@replyToDiscussionNote, nextRow.find(".js-discussion-reply-button")).call() | ||
else | ||
# add a notes row and insert the form | ||
row.after "<tr class=\"notes_holder js-temp-notes-holder\"><td class=\"notes_line\" colspan=\"2\"></td><td class=\"notes_content\"></td></tr>" | ||
form.clone().appendTo row.next().find(".notes_content") | ||
|
||
# show the form | ||
@setupDiscussionNoteForm $(link), row.next().find("form") | ||
|
||
### | ||
Called in response to "cancel" on a diff note form. | ||
Shows the reply button again. | ||
Removes the form and if necessary it's temporary row. | ||
### | ||
removeDiscussionNoteForm: (form)-> | ||
row = form.closest("tr") | ||
|
||
# show the reply button (will only work for replies) | ||
form.prev(".js-discussion-reply-button").show() | ||
if row.is(".js-temp-notes-holder") | ||
# remove temporary row for diff lines | ||
row.remove() | ||
else | ||
# only remove the form | ||
form.remove() | ||
|
||
@Notes = Notes |