diff --git a/app/assets/javascripts/diff_notes/components/resolve_comment_btn.js.es6 b/app/assets/javascripts/diff_notes/components/resolve_comment_btn.js.es6 new file mode 100644 index 0000000000000000000000000000000000000000..1ffe4cf99d6fb246a158cd7d4b95192d19cbddc8 --- /dev/null +++ b/app/assets/javascripts/diff_notes/components/resolve_comment_btn.js.es6 @@ -0,0 +1,31 @@ +((w) => { + w.ResolveCommentBtn = Vue.extend({ + props: { + discussionId: String + }, + computed: { + isDiscussionResolved: function () { + const notes = CommentsStore.notesForDiscussion(this.discussionId), + discussion = CommentsStore.state[this.discussionId]; + let allResolved = true; + + for (const noteId of notes) { + const note = discussion[noteId]; + + if (!note.resolved) { + allResolved = false; + } + } + + return allResolved; + }, + buttonText: function () { + if (this.isDiscussionResolved) { + return "Comment & unresolve discussion"; + } else { + return "Comment & resolve discussion"; + } + } + } + }); +}(window)); diff --git a/app/assets/javascripts/diff_notes/components/resolve_count.js.es6 b/app/assets/javascripts/diff_notes/components/resolve_count.js.es6 index dc9256b2d13815770edfbf23e3523b12ce85b289..7e099fbee8df925a8dc816a30c743bb60490cbfc 100644 --- a/app/assets/javascripts/diff_notes/components/resolve_count.js.es6 +++ b/app/assets/javascripts/diff_notes/components/resolve_count.js.es6 @@ -15,7 +15,7 @@ let resolved = true; for (const noteId in comments) { - const commentResolved = comments[noteId]; + const commentResolved = comments[noteId].resolved; if (!commentResolved) { resolved = false; diff --git a/app/assets/javascripts/diff_notes/diff_notes_bundle.js.es6 b/app/assets/javascripts/diff_notes/diff_notes_bundle.js.es6 index 0605ad0e75011022ca49cd9bf8ce66475d7ec75d..b856c7180342d427a57e8175a1fa95c39f38d76e 100644 --- a/app/assets/javascripts/diff_notes/diff_notes_bundle.js.es6 +++ b/app/assets/javascripts/diff_notes/diff_notes_bundle.js.es6 @@ -11,6 +11,7 @@ $(() => { components: { 'resolve-btn': ResolveBtn, 'resolve-all-btn': ResolveAllBtn, + 'resolve-comment-btn': ResolveCommentBtn, } }); diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js index cf951aa38999429778be3a4bc71d6f68cad15a7c..0b202f04163463336fde3feb9dd054e4e4e8e353 100644 --- a/app/assets/javascripts/notes.js +++ b/app/assets/javascripts/notes.js @@ -352,7 +352,7 @@ form.find("#note_line_code").remove(); form.find("#note_position").remove(); form.find("#note_type").remove(); - form.find('.js-comment-resolve-button').remove(); + form.find('.js-comment-resolve-button').closest('resolve-comment-btn').remove(); return this.parentTimeline = form.parents('.timeline'); }; @@ -397,8 +397,6 @@ Notes.prototype.addDiscussionNote = function(xhr, note, status) { var $form = $(xhr.target); - this.renderDiscussionNote(note); - this.removeDiscussionNoteForm($form); if ($form.attr('data-resolve-all') != null) { var namespacePath = $form.attr('data-namespace-path'), @@ -411,6 +409,9 @@ ResolveService.toggleResolveForDiscussion(namespace, mergeRequestId, discussionId); } } + + this.renderDiscussionNote(note); + this.removeDiscussionNoteForm($form); }; @@ -588,6 +589,7 @@ */ Notes.prototype.setupDiscussionNoteForm = function(dataHolder, form) { + var canResolve = dataHolder.attr('data-resolvable'); 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")); @@ -598,6 +600,16 @@ form.find("#note_noteable_type").val(dataHolder.data("noteableType")); form.find("#note_noteable_id").val(dataHolder.data("noteableId")); form.find('.js-note-discard').show().removeClass('js-note-discard').addClass('js-close-discussion-note-form').text(form.find('.js-close-discussion-note-form').data('cancel-text')); + + if (canResolve === 'false') { + form.find('resolve-comment-btn').remove(); + } else if (DiffNotesApp) { + var $commentBtn = form.find('resolve-comment-btn'); + $commentBtn + .attr(':discussion-id', `'${dataHolder.data("discussionId")}'`); + DiffNotesApp.$compile($commentBtn.get(0)); + } + this.setupNoteForm(form); form.find(".js-note-text").focus(); form diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb index 57d32165e702b3e0484e3a1f17eb01a0957aee64..87bf84adad14796ce73635430092093cf29653a6 100644 --- a/app/helpers/notes_helper.rb +++ b/app/helpers/notes_helper.rb @@ -79,7 +79,7 @@ module NotesHelper def link_to_reply_discussion(discussion, line_type = nil) return unless current_user - data = discussion.reply_attributes.merge(line_type: line_type) + data = discussion.reply_attributes.merge(line_type: line_type, resolvable: discussion.can_resolve?(current_user)) button_tag 'Reply...', class: 'btn btn-text-field js-discussion-reply-button', data: data, title: 'Add a reply' diff --git a/app/views/discussions/_resolve_all.html.haml b/app/views/discussions/_resolve_all.html.haml index 22eca5d8e7cd50ab9819b1708311ce241bdb938b..ae222205c4e3ede15cb909ff6ab748aa9a56c223 100644 --- a/app/views/discussions/_resolve_all.html.haml +++ b/app/views/discussions/_resolve_all.html.haml @@ -2,7 +2,7 @@ %resolve-all-btn{ ":namespace-path" => "'#{discussion.project.namespace.path}'", ":project-path" => "'#{discussion.project.path}'", ":discussion-id" => "'#{discussion.id}'", - ":merge-request-id" => "#{discussion.first_note.noteable.iid}", + ":merge-request-id" => "#{discussion.first_note.noteable.try(:iid)}", "inline-template" => true, "v-cloak" => true } %button.btn.btn-default{ type: "button", "@click" => "resolve", ":disabled" => "loading" } diff --git a/app/views/projects/merge_requests/_discussion.html.haml b/app/views/projects/merge_requests/_discussion.html.haml index 35c787ca7806d49e041cf34c8f0d4320507f4a47..d36d60be32e6fdfd5b4565fcf58315e3a07eb9c6 100644 --- a/app/views/projects/merge_requests/_discussion.html.haml +++ b/app/views/projects/merge_requests/_discussion.html.haml @@ -4,6 +4,8 @@ = link_to 'Close merge request', merge_request_path(@merge_request, merge_request: {state_event: :close }), method: :put, class: "btn btn-nr btn-comment btn-close close-mr-link js-note-target-close", title: "Close merge request", data: {original_text: "Close merge request", alternative_text: "Comment & close merge request"} - if @merge_request.closed? = link_to 'Reopen merge request', merge_request_path(@merge_request, merge_request: {state_event: :reopen }), method: :put, class: "btn btn-nr btn-comment btn-reopen reopen-mr-link js-note-target-reopen", title: "Reopen merge request", data: {original_text: "Reopen merge request", alternative_text: "Comment & reopen merge request"} - = submit_tag 'Comment & resolve discussion', class: "btn btn-nr btn-create append-right-10 comment-btn js-comment-resolve-button", data: { namespace_path: "#{@merge_request.project.namespace.path}", project_path: "#{@merge_request.project.path}" } + %resolve-comment-btn{ "inline-template" => true, ":discussion-id" => "" } + %button.btn.btn-nr.btn-default.append-right-10.js-comment-resolve-button{ type: "submit", data: { namespace_path: "#{@merge_request.project.namespace.path}", project_path: "#{@merge_request.project.path}" } } + {{ buttonText }} #notes= render "projects/notes/notes_with_form" diff --git a/app/views/projects/notes/_form.html.haml b/app/views/projects/notes/_form.html.haml index a9f2cd873fe948adcef286df6cc95ea47f7cd10d..032aeec70fd61b3593a052c9796ac2635f265a21 100644 --- a/app/views/projects/notes/_form.html.haml +++ b/app/views/projects/notes/_form.html.haml @@ -5,7 +5,7 @@ = f.hidden_field :commit_id = f.hidden_field :line_code = f.hidden_field :noteable_id - = hidden_field_tag :noteable_iid, @note.noteable.iid + = hidden_field_tag :noteable_iid, @note.noteable.try(:iid) = f.hidden_field :noteable_type = f.hidden_field :type = f.hidden_field :position