diff --git a/app/assets/javascripts/line_comments/application.js.coffee b/app/assets/javascripts/line_comments/application.js.coffee deleted file mode 100644 index d6894c54d04..00000000000 --- a/app/assets/javascripts/line_comments/application.js.coffee +++ /dev/null @@ -1,17 +0,0 @@ -#= require vue -#= require vue-resource -#= require_directory ./stores -#= require_directory ./services -#= require_directory ./components - -$ => - @DiffNotesApp = new Vue - el: '#diff-comments-app' - components: - 'resolve-btn': ResolveBtn - 'resolve-all': ResolveAll - - new Vue - el: '#resolve-count-app' - components: - 'resolve-count': ResolveCount diff --git a/app/assets/javascripts/line_comments/components/resolve_all.js.coffee b/app/assets/javascripts/line_comments/components/resolve_all.js.coffee deleted file mode 100644 index 86608eb5914..00000000000 --- a/app/assets/javascripts/line_comments/components/resolve_all.js.coffee +++ /dev/null @@ -1,21 +0,0 @@ -@ResolveAll = Vue.extend - props: - discussionId: String - namespace: String - data: -> - comments: CommentsStore.state - loadingObject: CommentsStore.loading - computed: - allResolved: -> - isResolved = true - for noteId, resolved of this.comments[this.discussionId] - isResolved = false unless resolved - isResolved - buttonText: -> - if this.allResolved then "Unresolve discussion" else "Resolve discussion" - loading: -> - this.loadingObject[this.discussionId] - methods: - resolve: -> - ResolveService - .resolveAll(this.namespace, this.discussionId, this.allResolved) diff --git a/app/assets/javascripts/line_comments/components/resolve_all.js.es6 b/app/assets/javascripts/line_comments/components/resolve_all.js.es6 new file mode 100644 index 00000000000..a1564a68096 --- /dev/null +++ b/app/assets/javascripts/line_comments/components/resolve_all.js.es6 @@ -0,0 +1,43 @@ +((w) => { + w.ResolveAll = Vue.extend({ + props: { + discussionId: String, + namespace: String, + }, + data: function() { + return { + comments: CommentsStore.state, + loadingObject: CommentsStore.loading, + }; + }, + computed: { + allResolved: function () { + let isResolved = true; + for (const noteId in this.comments[this.discussionId]) { + const resolved = this.comments[this.discussionId][noteId]; + + if (!resolved) { + isResolved = false; + } + } + return isResolved; + }, + buttonText: function () { + if (this.allResolved) { + return "Unresolve discussion"; + } else { + return "Resolve discussion"; + } + }, + loading: function () { + return this.loadingObject[this.discussionId]; + } + }, + methods: { + resolve: function () { + ResolveService + .resolveAll(this.namespace, this.discussionId, this.allResolved); + } + } + }); +}(window)); diff --git a/app/assets/javascripts/line_comments/components/resolve_btn.js.coffee b/app/assets/javascripts/line_comments/components/resolve_btn.js.coffee deleted file mode 100644 index 365df8c1988..00000000000 --- a/app/assets/javascripts/line_comments/components/resolve_btn.js.coffee +++ /dev/null @@ -1,31 +0,0 @@ -@ResolveBtn = Vue.extend - props: - noteId: Number - discussionId: String - resolved: Boolean - namespace: String - data: -> - comments: CommentsStore.state - loading: false - computed: - buttonText: -> - if this.isResolved then "Mark as unresolved" else "Mark as resolved" - isResolved: -> CommentsStore.get(this.discussionId, this.noteId) - methods: - updateTooltip: -> - $(this.$els.button) - .tooltip('hide') - .tooltip('fixTitle') - resolve: -> - this.loading = true - ResolveService - .resolve(this.namespace, this.discussionId, this.noteId, !this.isResolved) - .then => - this.loading = false - this.$nextTick this.updateTooltip - compiled: -> - $(this.$els.button).tooltip() - destroyed: -> - CommentsStore.delete(this.discussionId, this.noteId) - created: -> - CommentsStore.create(this.discussionId, this.noteId, this.resolved) diff --git a/app/assets/javascripts/line_comments/components/resolve_btn.js.es6 b/app/assets/javascripts/line_comments/components/resolve_btn.js.es6 new file mode 100644 index 00000000000..fa0e727c6d4 --- /dev/null +++ b/app/assets/javascripts/line_comments/components/resolve_btn.js.es6 @@ -0,0 +1,51 @@ +((w) => { + w.ResolveBtn = Vue.extend({ + props: { + noteId: Number, + discussionId: String, + resolved: Boolean, + namespace: String + }, + data: function () { + return { + comments: CommentsStore.state, + loading: false + }; + }, + computed: { + buttonText: function () { + if (this.isResolved) { + return "Mark as unresolved"; + } else { + return "Mark as resolved"; + } + }, + isResolved: function () { return CommentsStore.get(this.discussionId, this.noteId); }, + }, + methods: { + updateTooltip: function () { + $(this.$els.button) + .tooltip('hide') + .tooltip('fixTitle'); + }, + resolve: function () { + this.loading = true; + ResolveService + .resolve(this.namespace, this.discussionId, this.noteId, !this.isResolved) + .then(() => { + this.loading = false; + this.$nextTick(this.updateTooltip); + }); + } + }, + compiled: function () { + $(this.$els.button).tooltip(); + }, + destroyed: function () { + CommentsStore.delete(this.discussionId, this.noteId) + }, + created: function () { + CommentsStore.create(this.discussionId, this.noteId, this.resolved) + } + }); +}(window)); diff --git a/app/assets/javascripts/line_comments/components/resolve_count.js.coffee b/app/assets/javascripts/line_comments/components/resolve_count.js.coffee deleted file mode 100644 index 8e063600310..00000000000 --- a/app/assets/javascripts/line_comments/components/resolve_count.js.coffee +++ /dev/null @@ -1,17 +0,0 @@ -@ResolveCount = Vue.extend - data: -> - comments: CommentsStore.state - loading: false - computed: - resolved: -> - resolvedCount = 0 - for discussionId, comments of this.comments - resolved = true - for noteId, resolved of comments - resolved = false unless resolved - resolvedCount++ if resolved - resolvedCount - commentsCount: -> - Object.keys(this.comments).length - allResolved: -> - this.resolved is this.commentsCount diff --git a/app/assets/javascripts/line_comments/components/resolve_count.js.es6 b/app/assets/javascripts/line_comments/components/resolve_count.js.es6 new file mode 100644 index 00000000000..dc9256b2d13 --- /dev/null +++ b/app/assets/javascripts/line_comments/components/resolve_count.js.es6 @@ -0,0 +1,40 @@ +((w) => { + w.ResolveCount = Vue.extend({ + data: function () { + return { + comments: CommentsStore.state, + loading: false + }; + }, + computed: { + resolved: function () { + let resolvedCount = 0; + + for (const discussionId in this.comments) { + const comments = this.comments[discussionId]; + let resolved = true; + + for (const noteId in comments) { + const commentResolved = comments[noteId]; + + if (!commentResolved) { + resolved = false; + } + } + + if (resolved) { + resolvedCount++; + } + } + + return resolvedCount; + }, + commentsCount: function () { + return Object.keys(this.comments).length; + }, + allResolved: function () { + return this.resolved === this.commentsCount; + } + } + }); +}(window)); diff --git a/app/assets/javascripts/line_comments/line_comments_bundle.js.es6 b/app/assets/javascripts/line_comments/line_comments_bundle.js.es6 new file mode 100644 index 00000000000..6866e6b6f54 --- /dev/null +++ b/app/assets/javascripts/line_comments/line_comments_bundle.js.es6 @@ -0,0 +1,22 @@ +//= require vue +//= require vue-resource +//= require_directory ./stores +//= require_directory ./services +//= require_directory ./components + +$(() => { + window.DiffNotesApp = new Vue({ + el: '#diff-comments-app', + components: { + 'resolve-btn': ResolveBtn, + 'resolve-all': ResolveAll, + } + }); + + new Vue({ + el: '#resolve-count-app', + components: { + 'resolve-count': ResolveCount + } + }); +}); diff --git a/app/assets/javascripts/line_comments/services/resolve.js.coffee b/app/assets/javascripts/line_comments/services/resolve.js.coffee deleted file mode 100644 index 585f81d18af..00000000000 --- a/app/assets/javascripts/line_comments/services/resolve.js.coffee +++ /dev/null @@ -1,45 +0,0 @@ -class ResolveService - constructor: -> - actions = { - resolve: - method: 'POST' - url: 'notes{/id}/resolve' - all: - method: 'POST' - url: 'notes/resolve_all' - } - - @resource = Vue.resource('notes{/id}', {}, actions) - - setCSRF: -> - Vue.http.headers.common['X-CSRF-Token'] = $.rails.csrfToken() - - resolve: (namespace, discussionId, noteId, resolve) -> - @setCSRF() - Vue.http.options.root = "/#{namespace}" - - @resource - .resolve({ id: noteId }, { discussion: discussionId, resolved: resolve }) - .then (response) -> - if response.status is 200 - CommentsStore.update(discussionId, noteId, resolve) - - resolveAll: (namespace, discussionId, allResolve) -> - @setCSRF() - Vue.http.options.root = "/#{namespace}" - - ids = [] - for noteId, resolved of CommentsStore.state[discussionId] - ids.push(noteId) if resolved is allResolve - - CommentsStore.loading[discussionId] = true - @resource - .all({}, { ids: ids, discussion: discussionId, resolved: !allResolve }) - .then (response) -> - if response.status is 200 - for noteId in ids - CommentsStore.update(discussionId, noteId, !allResolve) - - CommentsStore.loading[discussionId] = false - -@ResolveService = new ResolveService() diff --git a/app/assets/javascripts/line_comments/services/resolve.js.es6 b/app/assets/javascripts/line_comments/services/resolve.js.es6 new file mode 100644 index 00000000000..e2be311cb15 --- /dev/null +++ b/app/assets/javascripts/line_comments/services/resolve.js.es6 @@ -0,0 +1,64 @@ +((w) => { + class ResolveServiceClass { + constructor() { + const actions = { + resolve: { + method: 'POST', + url: 'notes{/id}/resolve', + }, + all: { + method: 'POST', + url: 'notes/resolve_all', + } + }; + + this.resource = Vue.resource('notes{/id}', {}, actions); + } + + setCSRF() { + Vue.http.headers.common['X-CSRF-Token'] = $.rails.csrfToken(); + } + + resolve(namespace, discussionId, noteId, resolve) { + this.setCSRF(); + Vue.http.options.root = `/${namespace}`; + + return this.resource + .resolve({ id: noteId }, { discussion: discussionId, resolved: resolve }) + .then((response) => { + if (response.status === 200) { + CommentsStore.update(discussionId, noteId, resolve) + } + }); + } + + resolveAll(namespace, discussionId, allResolve) { + this.setCSRF(); + Vue.http.options.root = `/${namespace}`; + + let ids = [] + for (const noteId in CommentsStore.state[discussionId]) { + const resolved = CommentsStore.state[discussionId][noteId]; + + if (resolved === allResolve) { + ids.push(noteId); + } + } + + CommentsStore.loading[discussionId] = true; + return this.resource + .all({}, { ids: ids, discussion: discussionId, resolved: !allResolve }) + .then((response) => { + if (response.status === 200) { + for (const noteId in ids) { + CommentsStore.update(discussionId, noteId, !allResolve); + } + } + + CommentsStore.loading[discussionId] = false; + }); + } + } + + w.ResolveService = new ResolveServiceClass(); +}(window)); diff --git a/app/assets/javascripts/line_comments/stores/comments.js.coffee b/app/assets/javascripts/line_comments/stores/comments.js.coffee deleted file mode 100644 index 429fde7c063..00000000000 --- a/app/assets/javascripts/line_comments/stores/comments.js.coffee +++ /dev/null @@ -1,19 +0,0 @@ -@CommentsStore = - state: {} - loading: {} - get: (discussionId, noteId) -> - this.state[discussionId][noteId] - create: (discussionId, noteId, resolved) -> - unless this.state[discussionId]? - Vue.set(this.state, discussionId, {}) - Vue.set(this.loading, discussionId, false) - - Vue.set(this.state[discussionId], noteId, resolved) - update: (discussionId, noteId, resolved) -> - this.state[discussionId][noteId] = resolved - delete: (discussionId, noteId) -> - Vue.delete(this.state[discussionId], noteId) - - if Object.keys(this.state[discussionId]).length is 0 - Vue.delete(this.state, discussionId) - Vue.delete(this.loading, discussionId) diff --git a/app/assets/javascripts/line_comments/stores/comments.js.es6 b/app/assets/javascripts/line_comments/stores/comments.js.es6 new file mode 100644 index 00000000000..709361372ac --- /dev/null +++ b/app/assets/javascripts/line_comments/stores/comments.js.es6 @@ -0,0 +1,28 @@ +((w) => { + w.CommentsStore = { + state: {}, + loading: {}, + get: function (discussionId, noteId) { + return this.state[discussionId][noteId]; + }, + create: function (discussionId, noteId, resolved) { + if (!this.state[discussionId]) { + Vue.set(this.state, discussionId, {}); + Vue.set(this.loading, discussionId, false); + } + + Vue.set(this.state[discussionId], noteId, resolved); + }, + update: function (discussionId, noteId, resolved) { + this.state[discussionId][noteId] = resolved; + }, + delete: function (discussionId, noteId) { + Vue.delete(this.state[discussionId], noteId); + + if (Object.keys(this.state[discussionId]).length === 0) { + Vue.delete(this.state, discussionId); + Vue.delete(this.loading, discussionId); + } + }, + }; +}(window)); diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml index 0ba490c0f7f..14092c38a95 100644 --- a/app/views/projects/merge_requests/_show.html.haml +++ b/app/views/projects/merge_requests/_show.html.haml @@ -2,7 +2,7 @@ - page_description @merge_request.description - page_card_attributes @merge_request.card_attributes - content_for :page_specific_javascripts do - = page_specific_javascript_tag('line_comments/application.js') + = page_specific_javascript_tag('line_comments/line_comments_bundle.js') - if diff_view == 'parallel' - fluid_layout true diff --git a/config/application.rb b/config/application.rb index 54c82bbcf26..5a4b7fa3ee4 100644 --- a/config/application.rb +++ b/config/application.rb @@ -85,7 +85,7 @@ module Gitlab config.assets.precompile << "users/users_bundle.js" config.assets.precompile << "network/network_bundle.js" config.assets.precompile << "profile/profile_bundle.js" - config.assets.precompile << "line_comments/application.js" + config.assets.precompile << "line_comments/line_comments_bundle.js" config.assets.precompile << "lib/utils/*.js" config.assets.precompile << "lib/*.js" config.assets.precompile << "u2f.js"