diff options
author | Filipa Lacerda <filipa@gitlab.com> | 2017-10-09 09:14:38 +0100 |
---|---|---|
committer | Filipa Lacerda <filipa@gitlab.com> | 2017-10-09 09:14:38 +0100 |
commit | b6ab735ad2e596007d8dc0123bf5e2e018e99df8 (patch) | |
tree | 479d0fb7097caeeb132558b333cd2b8666118362 /app/assets/javascripts/notes.js | |
parent | fe5fe5242f67a7d91ff43659978892d507b71014 (diff) | |
parent | f45bb52af643cd271d415317f40b5541b18ec634 (diff) | |
download | gitlab-ce-38869-commitslist.tar.gz |
Merge branch 'master' into 38869-commitslist38869-commitslist
* master: (83 commits)
Move cycle analytics banner into a vue file
Remove executable permissions on images to make docs lint happy
Sync up hard coded DN class in migration
Redefine `respond_to?` in light of `method_missing`
Make internal methods private
Leave bad DNs alone instead of raising errors
Refactor DN error classes
Add changelog entry for LDAP normalization
Add migration specs
Move migration to background
Update DN class in migration
Normalize values, reusing DN normalization code
Remove telephoneNumber format comment
Fix space stripping
Rename method to `to_normalized_s`
Refactor initialize method for clarity
Move downcasing to normalize method
Normalize existing persisted DNs
Resolve Rubocop offenses
Switch to new DN class
...
Diffstat (limited to 'app/assets/javascripts/notes.js')
-rw-r--r-- | app/assets/javascripts/notes.js | 128 |
1 files changed, 119 insertions, 9 deletions
diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js index 93aa29454a0..24de21f2ce2 100644 --- a/app/assets/javascripts/notes.js +++ b/app/assets/javascripts/notes.js @@ -24,6 +24,7 @@ import './autosave'; import './dropzone_input'; import TaskList from './task_list'; import { ajaxPost, isInViewport, getPagePath, scrollToElement, isMetaKey } from './lib/utils/common_utils'; +import imageDiffHelper from './image_diff/helpers/index'; window.autosize = autosize; window.Dropzone = Dropzone; @@ -42,6 +43,7 @@ export default class Notes { this.visibilityChange = this.visibilityChange.bind(this); this.cancelDiscussionForm = this.cancelDiscussionForm.bind(this); this.onAddDiffNote = this.onAddDiffNote.bind(this); + this.onAddImageDiffNote = this.onAddImageDiffNote.bind(this); this.setupDiscussionNoteForm = this.setupDiscussionNoteForm.bind(this); this.onReplyToDiscussionNote = this.onReplyToDiscussionNote.bind(this); this.removeNote = this.removeNote.bind(this); @@ -114,6 +116,8 @@ export default class Notes { $(document).on('click', '.js-discussion-reply-button', this.onReplyToDiscussionNote); // add diff note $(document).on('click', '.js-add-diff-note-button', this.onAddDiffNote); + // add diff note for images + $(document).on('click', '.js-add-image-diff-note-button', this.onAddImageDiffNote); // hide diff note form $(document).on('click', '.js-close-discussion-note-form', this.cancelDiscussionForm); // toggle commit list @@ -140,6 +144,7 @@ export default class Notes { $(document).off('click', '.js-note-attachment-delete'); $(document).off('click', '.js-discussion-reply-button'); $(document).off('click', '.js-add-diff-note-button'); + $(document).off('click', '.js-add-image-diff-note-button'); $(document).off('visibilitychange'); $(document).off('keyup input', '.js-note-text'); $(document).off('click', '.js-note-target-reopen'); @@ -412,6 +417,11 @@ export default class Notes { this.note_ids.push(noteEntity.id); form = $form || $(`.js-discussion-note-form[data-discussion-id="${noteEntity.discussion_id}"]`); row = form.closest('tr'); + + if (noteEntity.on_image) { + row = form; + } + lineType = this.isParallelView() ? form.find('#line_type').val() : 'old'; diffAvatarContainer = row.prevAll('.line_holder').first().find('.js-avatar-container.' + lineType + '_line'); // is this the first note of discussion? @@ -423,7 +433,7 @@ export default class Notes { if (noteEntity.diff_discussion_html) { var $discussion = $(noteEntity.diff_discussion_html).renderGFM(); - if (!this.isParallelView() || row.hasClass('js-temp-notes-holder')) { + if (!this.isParallelView() || row.hasClass('js-temp-notes-holder') || noteEntity.on_image) { // insert the note and the reply button after the temp row row.after($discussion); } else { @@ -449,6 +459,7 @@ export default class Notes { if (typeof gl.diffNotesCompileComponents !== 'undefined' && noteEntity.discussion_resolvable) { gl.diffNotesCompileComponents(); + this.renderDiscussionAvatar(diffAvatarContainer, noteEntity); } @@ -561,7 +572,7 @@ export default class Notes { form.find('#note_line_code').val(), // DiffNote - form.find('#note_position').val() + form.find('#note_position').val(), ]; return new Autosave(textarea, key); } @@ -783,9 +794,22 @@ export default class Notes { $(`.js-diff-avatars-${discussionId}`).trigger('remove.vue'); // The notes tr can contain multiple lists of notes, like on the parallel diff - if (notesTr.find('.discussion-notes').length > 1) { + // notesTr does not exist for image diffs + if (notesTr.find('.discussion-notes').length > 1 || notesTr.length === 0) { + const $diffFile = $notes.closest('.diff-file'); + if ($diffFile.length > 0) { + const removeBadgeEvent = new CustomEvent('removeBadge.imageDiff', { + detail: { + // badgeNumber's start with 1 and index starts with 0 + badgeNumber: $notes.index() + 1, + }, + }); + + $diffFile[0].dispatchEvent(removeBadgeEvent); + } + $notes.remove(); - } else { + } else if (notesTr.length > 0) { notesTr.remove(); } } @@ -841,7 +865,11 @@ export default class Notes { */ setupDiscussionNoteForm(dataHolder, form) { // setup note target - const diffFileData = dataHolder.closest('.text-file'); + let diffFileData = dataHolder.closest('.text-file'); + + if (diffFileData.length === 0) { + diffFileData = dataHolder.closest('.image'); + } var discussionID = dataHolder.data('discussionId'); @@ -907,6 +935,31 @@ export default class Notes { }); } + onAddImageDiffNote(e) { + const $link = $(e.currentTarget || e.target); + const $diffFile = $link.closest('.diff-file'); + + const clickEvent = new CustomEvent('click.imageDiff', { + detail: e, + }); + + $diffFile[0].dispatchEvent(clickEvent); + + // Setup comment form + let newForm; + const $noteContainer = $link.closest('.diff-viewer').find('.note-container'); + const $form = $noteContainer.find('> .discussion-form'); + + if ($form.length === 0) { + newForm = this.cleanForm(this.formClone.clone()); + newForm.appendTo($noteContainer); + } else { + newForm = $form; + } + + this.setupDiscussionNoteForm($link, newForm); + } + toggleDiffNote({ target, lineType, @@ -999,10 +1052,25 @@ export default class Notes { } cancelDiscussionForm(e) { - var form; e.preventDefault(); - form = $(e.target).closest('.js-discussion-note-form'); - return this.removeDiscussionNoteForm(form); + const $form = $(e.target).closest('.js-discussion-note-form'); + const $discussionNote = $(e.target).closest('.discussion-notes'); + + if ($discussionNote.length === 0) { + // Only send blur event when the discussion form + // is not part of a discussion note + const $diffFile = $form.closest('.diff-file'); + + if ($diffFile.length > 0) { + const blurEvent = new CustomEvent('blur.imageDiff', { + detail: e, + }); + + $diffFile[0].dispatchEvent(blurEvent); + } + } + + return this.removeDiscussionNoteForm($form); } /** @@ -1414,6 +1482,15 @@ export default class Notes { // Submission successful! remove placeholder $notesContainer.find(`#${noteUniqueId}`).remove(); + const $diffFile = $form.closest('.diff-file'); + if ($diffFile.length > 0) { + const blurEvent = new CustomEvent('blur.imageDiff', { + detail: e, + }); + + $diffFile[0].dispatchEvent(blurEvent); + } + // Reset cached commands list when command is applied if (hasQuickActions) { $form.find('textarea.js-note-text').trigger('clear-commands-cache.atwho'); @@ -1436,7 +1513,28 @@ export default class Notes { } // Show final note element on UI - this.addDiscussionNote($form, note, $notesContainer.length === 0); + const isNewDiffComment = $notesContainer.length === 0; + this.addDiscussionNote($form, note, isNewDiffComment); + + if (isNewDiffComment) { + // Add image badge, avatar badge and toggle discussion badge for new image diffs + const notePosition = $form.find('#note_position').val(); + if ($diffFile.length > 0 && notePosition.length > 0) { + const { x, y, width, height } = JSON.parse(notePosition); + const addBadgeEvent = new CustomEvent('addBadge.imageDiff', { + detail: { + x, + y, + width, + height, + noteId: `note_${note.id}`, + discussionId: note.discussion_id, + }, + }); + + $diffFile[0].dispatchEvent(addBadgeEvent); + } + } // append flash-container to the Notes list if ($notesContainer.length) { @@ -1457,6 +1555,16 @@ export default class Notes { // Submission failed, remove placeholder note and show Flash error message $notesContainer.find(`#${noteUniqueId}`).remove(); + const blurEvent = new CustomEvent('blur.imageDiff', { + detail: e, + }); + + const closestDiffFile = $form.closest('.diff-file'); + + if (closestDiffFile.length) { + closestDiffFile[0].dispatchEvent(blurEvent); + } + if (hasQuickActions) { $notesContainer.find(`#${systemNoteUniqueId}`).remove(); } @@ -1500,6 +1608,8 @@ export default class Notes { const $noteBody = $editingNote.find('.js-task-list-container'); const $noteBodyText = $noteBody.find('.note-text'); const { formData, formContent, formAction } = this.getFormData($form); + const $diffFile = $form.closest('.diff-file'); + const $notesContainer = $form.closest('.notes'); // Cache original comment content const cachedNoteBodyText = $noteBodyText.html(); |