convert CS to JS

This commit is contained in:
Phil Hughes 2016-07-26 11:56:36 +01:00
parent 30f655c31a
commit c926cdfa4f
14 changed files with 250 additions and 152 deletions

View file

@ -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

View file

@ -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)

View file

@ -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));

View file

@ -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)

View file

@ -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));

View file

@ -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

View file

@ -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));

View file

@ -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
}
});
});

View file

@ -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()

View file

@ -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));

View file

@ -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)

View file

@ -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));

View file

@ -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

View file

@ -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"