Commit 433f1c42 authored by Phil Hughes's avatar Phil Hughes

Comment & resolve button no longer looks for can-resolve attribute

Fixed some bugs when removing notes
parent 538e66d7
...@@ -2,25 +2,31 @@ ...@@ -2,25 +2,31 @@
w.CommentAndResolveBtn = Vue.extend({ w.CommentAndResolveBtn = Vue.extend({
props: { props: {
discussionId: String, discussionId: String,
textareaVal: String textareaIsEmpty: Boolean
}, },
computed: { computed: {
discussion: function () {
return CommentsStore.state[this.discussionId];
},
showButton: function () {
if (!this.discussion) {
return false;
} else {
return this.discussion.canResolve();
}
},
isDiscussionResolved: function () { isDiscussionResolved: function () {
const discussion = CommentsStore.state[this.discussionId]; return this.discussion.isResolved();
return discussion.isResolved();
}, },
buttonText: function () { buttonText: function () {
const textVal = this.textareaVal;
if (this.isDiscussionResolved) { if (this.isDiscussionResolved) {
if (textVal === '') { if (this.textareaIsEmpty) {
return "Unresolve discussion"; return "Unresolve discussion";
} else { } else {
return "Comment & unresolve discussion"; return "Comment & unresolve discussion";
} }
} else { } else {
if (textVal === '') { if (this.textareaIsEmpty) {
return "Resolve discussion"; return "Resolve discussion";
} else { } else {
return "Comment & resolve discussion"; return "Comment & resolve discussion";
...@@ -30,10 +36,10 @@ ...@@ -30,10 +36,10 @@
}, },
ready: function () { ready: function () {
const $textarea = $(`#new-discussion-note-form-${this.discussionId} .note-textarea`); const $textarea = $(`#new-discussion-note-form-${this.discussionId} .note-textarea`);
this.textareaVal = $textarea.val(); this.textareaIsEmpty = $textarea.val() === '';
$textarea.on('input.comment-and-resolve-btn', () => { $textarea.on('input.comment-and-resolve-btn', () => {
this.textareaVal = $textarea.val(); this.textareaIsEmpty = $textarea.val() === '';
}); });
}, },
destroyed: function () { destroyed: function () {
......
(() => { (() => {
JumpToDiscussion = Vue.extend({ JumpToDiscussion = Vue.extend({
mixins: [DiscussionMixins],
props: { props: {
discussionId: String discussionId: String
}, },
...@@ -9,41 +10,25 @@ ...@@ -9,41 +10,25 @@
}; };
}, },
computed: { computed: {
allResolved: function () { discussion: function () {
const discussion = this.discussions[this.discussionId]; return this.discussions[this.discussionId];
if (discussion) {
return discussion.isResolved();
}
}, },
discussionsCount: function () { allResolved: function () {
return CommentsStore.discussionCount(); if (this.discussion) {
}, return this.unresolvedDiscussionCount === 0;
unresolvedDiscussionCount: function () {
let unresolvedCount = 0;
for (const discussionId in this.discussions) {
const discussion = this.discussions[discussionId];
if (!discussion.isResolved()) {
unresolvedCount++;
}
} }
return unresolvedCount;
}, },
showButton: function () { showButton: function () {
if (this.discussionId) { if (this.discussionId) {
if (this.unresolvedDiscussionCount > 1) { if (this.unresolvedDiscussionCount > 1) {
return true; return true;
} else { } else {
return this.discussionId !== this.lastResolvedId(); return this.discussionId !== this.lastResolvedId;
} }
} else { } else {
return this.unresolvedDiscussionCount >= 1; return this.unresolvedDiscussionCount >= 1;
} }
} },
},
methods: {
lastResolvedId: function () { lastResolvedId: function () {
let lastId; let lastId;
for (const discussionId in this.discussions) { for (const discussionId in this.discussions) {
...@@ -54,7 +39,9 @@ ...@@ -54,7 +39,9 @@
} }
} }
return lastId; return lastId;
}, }
},
methods: {
jumpToNextUnresolvedDiscussion: function () { jumpToNextUnresolvedDiscussion: function () {
let nextUnresolvedDiscussionId, let nextUnresolvedDiscussionId,
firstUnresolvedDiscussionId, firstUnresolvedDiscussionId,
...@@ -82,9 +69,7 @@ ...@@ -82,9 +69,7 @@
} }
} }
if (!nextUnresolvedDiscussionId && firstUnresolvedDiscussionId) { nextUnresolvedDiscussionId = nextUnresolvedDiscussionId || firstUnresolvedDiscussionId
nextUnresolvedDiscussionId = firstUnresolvedDiscussionId;
}
if (nextUnresolvedDiscussionId) { if (nextUnresolvedDiscussionId) {
mrTabs.activateTab('notes'); mrTabs.activateTab('notes');
......
...@@ -29,7 +29,9 @@ ...@@ -29,7 +29,9 @@
return this.discussions[this.discussionId]; return this.discussions[this.discussionId];
}, },
note: function () { note: function () {
return CommentsStore.get(this.discussionId, this.noteId); if (this.discussion) {
return this.discussion.getNote(this.noteId);
}
}, },
buttonText: function () { buttonText: function () {
if (this.isResolved) { if (this.isResolved) {
...@@ -39,7 +41,9 @@ ...@@ -39,7 +41,9 @@
} }
}, },
isResolved: function () { isResolved: function () {
return this.note.resolved; if (this.note) {
return this.note.resolved;
}
}, },
resolvedByName: function () { resolvedByName: function () {
return this.note.resolved_by; return this.note.resolved_by;
...@@ -87,11 +91,11 @@ ...@@ -87,11 +91,11 @@
container: 'body' container: 'body'
}); });
}, },
destroyed: function () { beforeDestroy: function () {
CommentsStore.delete(this.discussionId, this.noteId); CommentsStore.delete(this.discussionId, this.noteId);
}, },
created: function () { created: function () {
CommentsStore.create(this.discussionId, this.noteId, this.resolved, this.resolvedBy); CommentsStore.create(this.discussionId, this.noteId, this.canResolve, this.resolved, this.resolvedBy);
} }
}); });
})(window); })(window);
((w) => { ((w) => {
w.ResolveCount = Vue.extend({ w.ResolveCount = Vue.extend({
mixins: [DiscussionMixins],
props: { props: {
loggedOut: Boolean loggedOut: Boolean
}, },
data: function () { data: function () {
return { return {
discussions: CommentsStore.state, discussions: CommentsStore.state
loading: false
}; };
}, },
computed: { computed: {
resolved: function () {
let resolvedCount = 0;
for (const discussionId in this.discussions) {
const discussion = this.discussions[discussionId];
if (discussion.isResolved()) {
resolvedCount++;
}
}
return resolvedCount;
},
discussionCount: function () {
return Object.keys(this.discussions).length;
},
allResolved: function () { allResolved: function () {
return this.resolved === this.discussionCount; return this.resolved === this.discussionCount;
} }
......
...@@ -19,7 +19,9 @@ ...@@ -19,7 +19,9 @@
return this.discussions[this.discussionId]; return this.discussions[this.discussionId];
}, },
allResolved: function () { allResolved: function () {
return this.discussion.isResolved(); if (this.discussion) {
return this.discussion.isResolved();
}
}, },
buttonText: function () { buttonText: function () {
if (this.allResolved) { if (this.allResolved) {
...@@ -29,7 +31,9 @@ ...@@ -29,7 +31,9 @@
} }
}, },
loading: function () { loading: function () {
return this.discussion.loading; if (this.discussion) {
return this.discussion.loading;
}
} }
}, },
methods: { methods: {
......
((w) => {
w.DiscussionMixins = {
computed: {
discussionCount: function () {
return Object.keys(this.discussions).length;
},
resolved: function () {
let resolvedCount = 0;
for (const discussionId in this.discussions) {
const discussion = this.discussions[discussionId];
if (discussion.isResolved()) {
resolvedCount++;
}
}
return resolvedCount;
},
unresolvedDiscussionCount: function () {
let unresolvedCount = 0;
for (const discussionId in this.discussions) {
const discussion = this.discussions[discussionId];
if (!discussion.isResolved()) {
unresolvedCount++;
}
}
return unresolvedCount;
}
}
};
})(window);
...@@ -5,8 +5,8 @@ class DiscussionModel { ...@@ -5,8 +5,8 @@ class DiscussionModel {
this.loading = false; this.loading = false;
} }
createNote (noteId, resolved, resolved_by) { createNote (noteId, canResolve, resolved, resolved_by) {
Vue.set(this.notes, noteId, new NoteModel(this.id, noteId, resolved, resolved_by)); Vue.set(this.notes, noteId, new NoteModel(this.id, noteId, canResolve, resolved, resolved_by));
} }
deleteNote (noteId) { deleteNote (noteId) {
...@@ -67,4 +67,16 @@ class DiscussionModel { ...@@ -67,4 +67,16 @@ class DiscussionModel {
$discussionHeadline.remove(); $discussionHeadline.remove();
} }
} }
canResolve () {
for (const noteId in this.notes) {
const note = this.notes[noteId];
if (note.canResolve) {
return true;
}
}
return false;
}
} }
class NoteModel { class NoteModel {
constructor (discussionId, noteId, resolved, resolved_by) { constructor (discussionId, noteId, canResolve, resolved, resolved_by) {
this.discussionId = discussionId; this.discussionId = discussionId;
this.id = noteId; this.id = noteId;
this.canResolve = canResolve;
this.resolved = resolved; this.resolved = resolved;
this.resolved_by = resolved_by; this.resolved_by = resolved_by;
} }
......
...@@ -9,20 +9,21 @@ ...@@ -9,20 +9,21 @@
Vue.http.headers.common['X-CSRF-Token'] = $.rails.csrfToken(); Vue.http.headers.common['X-CSRF-Token'] = $.rails.csrfToken();
} }
resolve(namespace, noteId) { prepareRequest(namespace) {
this.setCSRF(); this.setCSRF();
if (Vue.http.options.root !== `/${namespace}`) { if (Vue.http.options.root !== `/${namespace}`) {
Vue.http.options.root = `/${namespace}`; Vue.http.options.root = `/${namespace}`;
} }
}
resolve(namespace, noteId) {
this.prepareRequest(namespace);
return this.noteResource.save({ noteId }, {}); return this.noteResource.save({ noteId }, {});
} }
unresolve(namespace, noteId) { unresolve(namespace, noteId) {
this.setCSRF(); this.prepareRequest(namespace);
if (Vue.http.options.root !== `/${namespace}`) {
Vue.http.options.root = `/${namespace}`;
}
return this.noteResource.delete({ noteId }, {}); return this.noteResource.delete({ noteId }, {});
} }
...@@ -61,11 +62,7 @@ ...@@ -61,11 +62,7 @@
resolveAll(namespace, mergeRequestId, discussionId) { resolveAll(namespace, mergeRequestId, discussionId) {
const discussion = CommentsStore.state[discussionId]; const discussion = CommentsStore.state[discussionId];
this.setCSRF(); this.prepareRequest(namespace);
if (Vue.http.options.root !== `/${namespace}`) {
Vue.http.options.root = `/${namespace}`;
}
discussion.loading = true; discussion.loading = true;
...@@ -78,8 +75,7 @@ ...@@ -78,8 +75,7 @@
unResolveAll(namespace, mergeRequestId, discussionId) { unResolveAll(namespace, mergeRequestId, discussionId) {
const discussion = CommentsStore.state[discussionId]; const discussion = CommentsStore.state[discussionId];
this.setCSRF(); this.prepareRequest(namespace);
Vue.http.options.root = `/${namespace}`;
discussion.loading = true; discussion.loading = true;
......
...@@ -4,14 +4,14 @@ ...@@ -4,14 +4,14 @@
get: function (discussionId, noteId) { get: function (discussionId, noteId) {
return this.state[discussionId].getNote(noteId); return this.state[discussionId].getNote(noteId);
}, },
create: function (discussionId, noteId, resolved, resolved_by) { create: function (discussionId, noteId, canResolve, resolved, resolved_by) {
let discussion = this.state[discussionId]; let discussion = this.state[discussionId];
if (!this.state[discussionId]) { if (!this.state[discussionId]) {
discussion = new DiscussionModel(discussionId); discussion = new DiscussionModel(discussionId);
Vue.set(this.state, discussionId, discussion); Vue.set(this.state, discussionId, discussion);
} }
discussion.createNote(noteId, resolved, resolved_by); discussion.createNote(noteId, canResolve, resolved, resolved_by);
}, },
update: function (discussionId, noteId, resolved, resolved_by) { update: function (discussionId, noteId, resolved, resolved_by) {
const discussion = this.state[discussionId]; const discussion = this.state[discussionId];
...@@ -26,9 +26,6 @@ ...@@ -26,9 +26,6 @@
if (discussion.notesCount() === 0) { if (discussion.notesCount() === 0) {
Vue.delete(this.state, discussionId); Vue.delete(this.state, discussionId);
} }
},
discussionCount: function () {
return Object.keys(this.state).length
} }
}; };
})(window); })(window);
...@@ -577,7 +577,6 @@ ...@@ -577,7 +577,6 @@
*/ */
Notes.prototype.setupDiscussionNoteForm = function(dataHolder, form) { Notes.prototype.setupDiscussionNoteForm = function(dataHolder, form) {
var canResolve = dataHolder.attr('data-can-resolve');
form.attr('id', "new-discussion-note-form-" + (dataHolder.data("discussionId"))); form.attr('id', "new-discussion-note-form-" + (dataHolder.data("discussionId")));
form.attr("data-line-code", dataHolder.data("lineCode")); form.attr("data-line-code", dataHolder.data("lineCode"));
form.find("#note_type").val(dataHolder.data("noteType")); form.find("#note_type").val(dataHolder.data("noteType"));
...@@ -591,9 +590,7 @@ ...@@ -591,9 +590,7 @@
form.find('.js-note-target-close').remove(); form.find('.js-note-target-close').remove();
this.setupNoteForm(form); this.setupNoteForm(form);
if (canResolve === 'false' || !form.closest('.notes_content').find('.note:not(.system-note)').length) { if (typeof DiffNotesApp !== 'undefined') {
form.find('comment-and-resolve-btn').remove();
} else if (typeof DiffNotesApp !== 'undefined') {
var $commentBtn = form.find('comment-and-resolve-btn'); var $commentBtn = form.find('comment-and-resolve-btn');
$commentBtn $commentBtn
.attr(':discussion-id', "'" + dataHolder.data('discussionId') + "'"); .attr(':discussion-id', "'" + dataHolder.data('discussionId') + "'");
......
...@@ -79,7 +79,7 @@ module NotesHelper ...@@ -79,7 +79,7 @@ module NotesHelper
def link_to_reply_discussion(discussion, line_type = nil) def link_to_reply_discussion(discussion, line_type = nil)
return unless current_user return unless current_user
data = discussion.reply_attributes.merge(line_type: line_type, can_resolve: discussion.can_resolve?(current_user)) data = discussion.reply_attributes.merge(line_type: line_type)
button_tag 'Reply...', class: 'btn btn-text-field js-discussion-reply-button', button_tag 'Reply...', class: 'btn btn-text-field js-discussion-reply-button',
data: data, title: 'Add a reply' data: data, title: 'Add a reply'
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
- if @merge_request.closed? - 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"} = 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"}
%comment-and-resolve-btn{ "inline-template" => true, ":discussion-id" => "" } %comment-and-resolve-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}" } } %button.btn.btn-nr.btn-default.append-right-10.js-comment-resolve-button{ "v-if" => "showButton", type: "submit", data: { namespace_path: "#{@merge_request.project.namespace.path}", project_path: "#{@merge_request.project.path}" } }
{{ buttonText }} {{ buttonText }}
#notes= render "projects/notes/notes_with_form" #notes= render "projects/notes/notes_with_form"
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