Added resolved by users name into tooltip

This commit is contained in:
Phil Hughes 2016-07-26 15:47:19 +01:00
parent 5e8606562d
commit a678fef836
9 changed files with 65 additions and 44 deletions

View file

@ -19,7 +19,7 @@
allResolved: function () { allResolved: function () {
let isResolved = true; let isResolved = true;
for (const noteId in this.comments[this.discussionId]) { for (const noteId in this.comments[this.discussionId]) {
const resolved = this.comments[this.discussionId][noteId]; const resolved = this.comments[this.discussionId][noteId].resolved;
if (!resolved) { if (!resolved) {
isResolved = false; isResolved = false;

View file

@ -9,6 +9,8 @@
resolved: Boolean, resolved: Boolean,
namespacePath: String, namespacePath: String,
projectPath: String, projectPath: String,
canResolve: Boolean,
resolvedBy: String
}, },
data: function () { data: function () {
return { return {
@ -18,19 +20,24 @@
}, },
computed: { computed: {
buttonText: function () { buttonText: function () {
if (!this.canResolve) return;
if (this.isResolved) { if (this.isResolved) {
return "Mark as unresolved"; return `Resolved by ${this.resolvedByName}`;
} else { } else {
return "Mark as resolved"; return 'Mark as resolved';
} }
}, },
isResolved: function () { return CommentsStore.get(this.discussionId, this.noteId); }, isResolved: function () { return CommentsStore.get(this.discussionId, this.noteId).resolved; },
resolvedByName: function () { return CommentsStore.get(this.discussionId, this.noteId).user; },
}, },
methods: { methods: {
updateTooltip: function () { updateTooltip: function () {
$(this.$els.button) if (this.canResolve) {
.tooltip('hide') $(this.$els.button)
.tooltip('fixTitle'); .tooltip('hide')
.tooltip('fixTitle');
}
}, },
resolve: function () { resolve: function () {
let promise; let promise;
@ -45,10 +52,12 @@
} }
promise.then((response) => { promise.then((response) => {
const data = response.data;
const user = data ? data.resolved_by : null;
this.loading = false; this.loading = false;
if (response.status === 200) { if (response.status === 200) {
CommentsStore.update(this.discussionId, this.noteId, !this.isResolved); CommentsStore.update(this.discussionId, this.noteId, !this.isResolved, user);
} }
this.$nextTick(this.updateTooltip); this.$nextTick(this.updateTooltip);
@ -56,13 +65,17 @@
} }
}, },
compiled: function () { compiled: function () {
$(this.$els.button).tooltip(); if (this.canResolve) {
$(this.$els.button).tooltip({
container: 'body'
});
}
}, },
destroyed: function () { destroyed: 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) CommentsStore.create(this.discussionId, this.noteId, this.resolved, this.resolvedBy);
} }
}); });
}(window)); }(window));

View file

@ -28,7 +28,7 @@
let isResolved = true; let isResolved = true;
for (const noteId of noteIds) { for (const noteId of noteIds) {
const resolved = CommentsStore.state[discussionId][noteId]; const resolved = CommentsStore.state[discussionId][noteId].resolved;
if (!resolved) { if (!resolved) {
isResolved = false; isResolved = false;
@ -52,9 +52,11 @@
mergeRequestId, mergeRequestId,
discussionId discussionId
}, {}).then((response) => { }, {}).then((response) => {
const data = response.data;
const user = data ? data.resolved_by : null;
CommentsStore.loading[discussionId] = false; CommentsStore.loading[discussionId] = false;
CommentsStore.updateCommentsForDiscussion(discussionId, true); CommentsStore.updateCommentsForDiscussion(discussionId, true, user);
}); });
} }

View file

@ -5,16 +5,17 @@
get: function (discussionId, noteId) { get: function (discussionId, noteId) {
return this.state[discussionId][noteId]; return this.state[discussionId][noteId];
}, },
create: function (discussionId, noteId, resolved) { create: function (discussionId, noteId, resolved, user) {
if (!this.state[discussionId]) { if (!this.state[discussionId]) {
Vue.set(this.state, discussionId, {}); Vue.set(this.state, discussionId, {});
Vue.set(this.loading, discussionId, false); Vue.set(this.loading, discussionId, false);
} }
Vue.set(this.state[discussionId], noteId, resolved); Vue.set(this.state[discussionId], noteId, { resolved, user});
}, },
update: function (discussionId, noteId, resolved) { update: function (discussionId, noteId, resolved, user) {
this.state[discussionId][noteId] = resolved; this.state[discussionId][noteId].resolved = resolved;
this.state[discussionId][noteId].user = user;
}, },
delete: function (discussionId, noteId) { delete: function (discussionId, noteId) {
Vue.delete(this.state[discussionId], noteId); Vue.delete(this.state[discussionId], noteId);
@ -24,11 +25,11 @@
Vue.delete(this.loading, discussionId); Vue.delete(this.loading, discussionId);
} }
}, },
updateCommentsForDiscussion: function (discussionId, resolve) { updateCommentsForDiscussion: function (discussionId, resolve, user) {
const noteIds = CommentsStore.resolvedNotesForDiscussion(discussionId, resolve); const noteIds = CommentsStore.resolvedNotesForDiscussion(discussionId, resolve);
for (const noteId of noteIds) { for (const noteId of noteIds) {
CommentsStore.update(discussionId, noteId, resolve); CommentsStore.update(discussionId, noteId, resolve, user);
} }
}, },
notesForDiscussion: function (discussionId) { notesForDiscussion: function (discussionId) {
@ -44,7 +45,7 @@
let ids = []; let ids = [];
for (const noteId in CommentsStore.state[discussionId]) { for (const noteId in CommentsStore.state[discussionId]) {
const resolved = CommentsStore.state[discussionId][noteId]; const resolved = CommentsStore.state[discussionId][noteId].resolved;
if (resolved !== resolve) { if (resolved !== resolve) {
ids.push(noteId); ids.push(noteId);

View file

@ -411,7 +411,7 @@ ul.notes {
outline: 0; outline: 0;
vertical-align: middle; vertical-align: middle;
&:hover, &:not(.is-disabled):hover,
&.is-active { &.is-active {
color: #fff; color: #fff;
background-color: $gl-text-green; background-color: $gl-text-green;

View file

@ -9,7 +9,9 @@ class Projects::DiscussionsController < Projects::ApplicationController
discussion.resolve!(current_user) discussion.resolve!(current_user)
head :ok render json: {
resolved_by: discussion.resolved_by.try(:name)
}
end end
def unresolve def unresolve

View file

@ -72,7 +72,9 @@ class Projects::NotesController < Projects::ApplicationController
note.resolve!(current_user) note.resolve!(current_user)
head :ok render json: {
resolved_by: note.resolved_by.try(:name)
}
end end
def unresolve def unresolve

View file

@ -1,4 +1,4 @@
- if discussion.can_resolve?(current_user) - if discussion.can_resolve?(current_user) && discussion.resolvable?
%resolve-all-btn{ ":namespace-path" => "'#{discussion.project.namespace.path}'", %resolve-all-btn{ ":namespace-path" => "'#{discussion.project.namespace.path}'",
":project-path" => "'#{discussion.project.path}'", ":project-path" => "'#{discussion.project.path}'",
":discussion-id" => "'#{discussion.id}'", ":discussion-id" => "'#{discussion.id}'",

View file

@ -23,28 +23,29 @@
%span.note-role.hidden-xs= access %span.note-role.hidden-xs= access
- if note.resolvable? - if note.resolvable?
- if can?(current_user, :resolve_note, note) %resolve-btn{ ":namespace-path" => "'#{note.project.namespace.path}'",
%resolve-btn{ ":namespace-path" => "'#{note.project.namespace.path}'", ":project-path" => "'#{note.project.path}'",
":project-path" => "'#{note.project.path}'", ":discussion-id" => "'#{note.discussion_id}'",
":discussion-id" => "'#{note.discussion_id}'", ":note-id" => note.id,
":note-id" => note.id, ":resolved" => note.resolved?,
":resolved" => note.resolved?, ":can-resolve" => can?(current_user, :resolve_note, note),
"inline-template" => true, ":resolved-by" => "'#{note.resolved_by.try(:name)}'",
"v-ref:note_#{note.id}" => true } "inline-template" => true,
"v-ref:note_#{note.id}" => true }
.note-action-button .note-action-button
= icon("spin spinner", "v-show" => "loading") = icon("spin spinner", "v-show" => "loading")
%button.line-resolve-btn{ type: "button", %button.line-resolve-btn{ type: "button",
":class" => "{ 'is-active': isResolved }", class: ("is-disabled" if !can?(current_user, :resolve_note, note)),
":aria-label" => "buttonText", ":class" => "{ 'is-active': isResolved }",
"@click" => "resolve", ":aria-label" => "buttonText",
":title" => "buttonText", ":disabled" => !can?(current_user, :resolve_note, note),
"v-show" => "!loading", "@click" => "resolve",
"v-el:button" => true } ":title" => "buttonText",
"v-show" => "!loading",
"v-el:button" => true }
= icon("check") = icon("check")
- else
-# TODO: Just render status
- if current_user - if current_user
- if note.emoji_awardable? - if note.emoji_awardable?