Skip to content
Snippets Groups Projects
Commit f9c58d93 authored by Phil Hughes's avatar Phil Hughes
Browse files

Refactored diff notes Vue app

It now relies on its Vue bundle rather than the window. Fixes some reactivity issues that was happening in EE
parent 4975f416
No related branches found
No related tags found
No related merge requests found
Showing
with 58 additions and 67 deletions
/* eslint-disable comma-dangle, object-shorthand, func-names, no-else-return, quotes, no-lonely-if, max-len */
/* global Vue */
/* global CommentsStore */
const Vue = require('vue');
 
(() => {
const CommentAndResolveBtn = Vue.extend({
Loading
Loading
@@ -9,13 +9,11 @@
},
data() {
return {
textareaIsEmpty: true
textareaIsEmpty: true,
discussion: {},
};
},
computed: {
discussion: function () {
return CommentsStore.state[this.discussionId];
},
showButton: function () {
if (this.discussion) {
return this.discussion.isResolvable();
Loading
Loading
@@ -42,6 +40,9 @@
}
}
},
created() {
this.discussion = CommentsStore.state[this.discussionId];
},
mounted: function () {
const $textarea = $(`#new-discussion-note-form-${this.discussionId} .note-textarea`);
this.textareaIsEmpty = $textarea.val() === '';
Loading
Loading
/* eslint-disable comma-dangle, object-shorthand, func-names, no-else-return, guard-for-in, no-restricted-syntax, one-var, space-before-function-paren, no-lonely-if, no-continue, brace-style, max-len, quotes */
/* global Vue */
/* global DiscussionMixins */
/* global CommentsStore */
const Vue = require('vue');
 
(() => {
const JumpToDiscussion = Vue.extend({
Loading
Loading
@@ -12,12 +12,10 @@
data: function () {
return {
discussions: CommentsStore.state,
discussion: {},
};
},
computed: {
discussion: function () {
return this.discussions[this.discussionId];
},
allResolved: function () {
return this.unresolvedDiscussionCount === 0;
},
Loading
Loading
@@ -186,7 +184,10 @@
offset: -($('.navbar-gitlab').outerHeight() + $('.layout-nav').outerHeight())
});
}
}
},
created() {
this.discussion = this.discussions[this.discussionId];
},
});
 
Vue.component('jump-to-discussion', JumpToDiscussion);
Loading
Loading
/* eslint-disable comma-dangle, object-shorthand, func-names, quote-props, no-else-return, camelcase, no-new, max-len */
/* global Vue */
/* global CommentsStore */
/* global ResolveService */
/* global Flash */
const Vue = require('vue');
 
(() => {
const ResolveBtn = Vue.extend({
Loading
Loading
@@ -10,14 +10,14 @@
noteId: Number,
discussionId: String,
resolved: Boolean,
projectPath: String,
canResolve: Boolean,
resolvedBy: String
},
data: function () {
return {
discussions: CommentsStore.state,
loading: false
loading: false,
note: {},
};
},
watch: {
Loading
Loading
@@ -30,13 +30,6 @@
discussion: function () {
return this.discussions[this.discussionId];
},
note: function () {
if (this.discussion) {
return this.discussion.getNote(this.noteId);
} else {
return undefined;
}
},
buttonText: function () {
if (this.isResolved) {
return `Resolved by ${this.resolvedByName}`;
Loading
Loading
@@ -73,10 +66,10 @@
 
if (this.isResolved) {
promise = ResolveService
.unresolve(this.projectPath, this.noteId);
.unresolve(this.noteId);
} else {
promise = ResolveService
.resolve(this.projectPath, this.noteId);
.resolve(this.noteId);
}
 
promise.then((response) => {
Loading
Loading
@@ -106,6 +99,8 @@
},
created: function () {
CommentsStore.create(this.discussionId, this.noteId, this.canResolve, this.resolved, this.resolvedBy);
this.note = this.discussion.getNote(this.noteId);
}
});
 
Loading
Loading
/* eslint-disable comma-dangle, object-shorthand, func-names, no-param-reassign */
/* global Vue */
/* global DiscussionMixins */
/* global CommentsStore */
const Vue = require('vue');
 
((w) => {
w.ResolveCount = Vue.extend({
Loading
Loading
/* eslint-disable object-shorthand, func-names, space-before-function-paren, comma-dangle, no-else-return, quotes, max-len */
/* global Vue */
/* global CommentsStore */
/* global ResolveService */
 
const Vue = require('vue');
(() => {
const ResolveDiscussionBtn = Vue.extend({
props: {
discussionId: String,
mergeRequestId: Number,
projectPath: String,
canResolve: Boolean,
},
data: function() {
return {
discussions: CommentsStore.state
discussion: {},
};
},
computed: {
discussion: function () {
return this.discussions[this.discussionId];
},
showButton: function () {
if (this.discussion) {
return this.discussion.isResolvable();
Loading
Loading
@@ -51,11 +48,13 @@
},
methods: {
resolve: function () {
ResolveService.toggleResolveForDiscussion(this.projectPath, this.mergeRequestId, this.discussionId);
ResolveService.toggleResolveForDiscussion(this.mergeRequestId, this.discussionId);
}
},
created: function () {
CommentsStore.createDiscussion(this.discussionId, this.canResolve);
this.discussion = CommentsStore.state[this.discussionId];
}
});
 
Loading
Loading
Loading
Loading
@@ -3,6 +3,7 @@
/* global ResolveCount */
 
function requireAll(context) { return context.keys().map(context); }
const Vue = require('vue');
requireAll(require.context('./models', false, /^\.\/.*\.(js|es6)$/));
requireAll(require.context('./stores', false, /^\.\/.*\.(js|es6)$/));
requireAll(require.context('./services', false, /^\.\/.*\.(js|es6)$/));
Loading
Loading
@@ -10,11 +11,14 @@ requireAll(require.context('./mixins', false, /^\.\/.*\.(js|es6)$/));
requireAll(require.context('./components', false, /^\.\/.*\.(js|es6)$/));
 
$(() => {
const projectPath = document.querySelector('.merge-request').dataset.projectPath;
const COMPONENT_SELECTOR = 'resolve-btn, resolve-discussion-btn, jump-to-discussion, comment-and-resolve-btn';
 
window.gl = window.gl || {};
window.gl.diffNoteApps = {};
 
window.ResolveService = new gl.DiffNotesResolveServiceClass(projectPath);
gl.diffNotesCompileComponents = () => {
const $components = $(COMPONENT_SELECTOR).filter(function () {
return $(this).closest('resolve-count').length !== 1;
Loading
Loading
/* eslint-disable class-methods-use-this, one-var, camelcase, no-new, comma-dangle, no-param-reassign, max-len */
/* global Vue */
/* global Flash */
/* global CommentsStore */
 
((w) => {
class ResolveServiceClass {
constructor() {
this.noteResource = Vue.resource('notes{/noteId}/resolve');
this.discussionResource = Vue.resource('merge_requests{/mergeRequestId}/discussions{/discussionId}/resolve');
}
const Vue = window.Vue = require('vue');
window.Vue.use(require('vue-resource'));
 
setCSRF() {
Vue.http.headers.common['X-CSRF-Token'] = $.rails.csrfToken();
}
(() => {
window.gl = window.gl || {};
 
prepareRequest(root) {
this.setCSRF();
Vue.http.options.root = root;
}
class ResolveServiceClass {
constructor(root) {
this.noteResource = Vue.resource(`${root}/notes{/noteId}/resolve`);
this.discussionResource = Vue.resource(`${root}/merge_requests{/mergeRequestId}/discussions{/discussionId}/resolve`);
 
resolve(projectPath, noteId) {
this.prepareRequest(projectPath);
Vue.http.interceptors.push((request, next) => {
if ($.rails) {
request.headers['X-CSRF-Token'] = $.rails.csrfToken();
}
next();
});
}
 
resolve(noteId) {
return this.noteResource.save({ noteId }, {});
}
 
unresolve(projectPath, noteId) {
this.prepareRequest(projectPath);
unresolve(noteId) {
return this.noteResource.delete({ noteId }, {});
}
 
toggleResolveForDiscussion(projectPath, mergeRequestId, discussionId) {
toggleResolveForDiscussion(mergeRequestId, discussionId) {
const discussion = CommentsStore.state[discussionId];
const isResolved = discussion.isResolved();
let promise;
 
if (isResolved) {
promise = this.unResolveAll(projectPath, mergeRequestId, discussionId);
promise = this.unResolveAll(mergeRequestId, discussionId);
} else {
promise = this.resolveAll(projectPath, mergeRequestId, discussionId);
promise = this.resolveAll(mergeRequestId, discussionId);
}
 
promise.then((response) => {
Loading
Loading
@@ -62,11 +60,9 @@
});
}
 
resolveAll(projectPath, mergeRequestId, discussionId) {
resolveAll(mergeRequestId, discussionId) {
const discussion = CommentsStore.state[discussionId];
 
this.prepareRequest(projectPath);
discussion.loading = true;
 
return this.discussionResource.save({
Loading
Loading
@@ -75,11 +71,9 @@
}, {});
}
 
unResolveAll(projectPath, mergeRequestId, discussionId) {
unResolveAll(mergeRequestId, discussionId) {
const discussion = CommentsStore.state[discussionId];
 
this.prepareRequest(projectPath);
discussion.loading = true;
 
return this.discussionResource.delete({
Loading
Loading
@@ -89,5 +83,5 @@
}
}
 
w.ResolveService = new ResolveServiceClass();
})(window);
gl.DiffNotesResolveServiceClass = ResolveServiceClass;
})();
Loading
Loading
@@ -455,7 +455,7 @@ require('vendor/task_list');
var mergeRequestId = $form.data('noteable-iid');
 
if (ResolveService != null) {
ResolveService.toggleResolveForDiscussion(projectPath, mergeRequestId, discussionId);
ResolveService.toggleResolveForDiscussion(mergeRequestId, discussionId);
}
}
 
Loading
Loading
- if discussion.for_merge_request?
%resolve-discussion-btn{ ":project-path" => "'#{project_path(discussion.project)}'",
":discussion-id" => "'#{discussion.id}'",
%resolve-discussion-btn{ ":discussion-id" => "'#{discussion.id}'",
":merge-request-id" => discussion.noteable.iid,
":can-resolve" => discussion.can_resolve?(current_user),
"inline-template" => true }
Loading
Loading
Loading
Loading
@@ -3,10 +3,9 @@
- page_description @merge_request.description
- page_card_attributes @merge_request.card_attributes
- content_for :page_specific_javascripts do
= page_specific_javascript_bundle_tag('lib_vue')
= page_specific_javascript_bundle_tag('diff_notes')
 
.merge-request{ 'data-url' => merge_request_path(@merge_request) }
.merge-request{ 'data-url' => merge_request_path(@merge_request), 'data-project-path' => project_path(@merge_request.project) }
= render "projects/merge_requests/show/mr_title"
 
.merge-request-details.issuable-details{ data: { id: @merge_request.project.id } }
Loading
Loading
Loading
Loading
@@ -30,8 +30,7 @@
 
- if note.resolvable?
- can_resolve = can?(current_user, :resolve_note, note)
%resolve-btn{ "project-path" => "#{project_path(note.project)}",
"discussion-id" => "#{note.discussion_id}",
%resolve-btn{ "discussion-id" => "#{note.discussion_id}",
":note-id" => note.id,
":resolved" => note.resolved?,
":can-resolve" => can_resolve,
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment