es6
This commit is contained in:
29
Gruntfile.js
29
Gruntfile.js
@@ -13,7 +13,7 @@ module.exports = function(grunt) {
|
||||
|
||||
js: {
|
||||
files: ['app/assets/javascripts/**/*.js'],
|
||||
tasks: ['concat', 'babel'],
|
||||
tasks: [ 'concat:app', 'babel', 'browserify', 'concat:dist'],
|
||||
options: {
|
||||
spawn: false,
|
||||
},
|
||||
@@ -21,7 +21,7 @@ module.exports = function(grunt) {
|
||||
|
||||
css: {
|
||||
files: ['app/assets/stylesheets/**/*.scss'],
|
||||
tasks: ['sass', 'concat'],
|
||||
tasks: ['sass', 'concat:css'],
|
||||
options: {
|
||||
spawn: false,
|
||||
},
|
||||
@@ -73,7 +73,7 @@ module.exports = function(grunt) {
|
||||
'app/assets/javascripts/app/*.js',
|
||||
'app/assets/javascripts/app/frontend/*.js',
|
||||
'app/assets/javascripts/app/frontend/controllers/*.js',
|
||||
'app/assets/javascripts/app/frontend/models/*.js',
|
||||
'app/assets/javascripts/app/frontend/models/**/*.js',
|
||||
'app/assets/javascripts/app/services/*.js',
|
||||
'app/assets/javascripts/app/services/directives/*.js',
|
||||
'app/assets/javascripts/app/services/helpers/*.js',
|
||||
@@ -99,7 +99,7 @@ module.exports = function(grunt) {
|
||||
},
|
||||
|
||||
dist: {
|
||||
src: ['vendor/assets/javascripts/lib.js', 'vendor/assets/javascripts/app.js', 'vendor/assets/javascripts/templates.js'],
|
||||
src: ['vendor/assets/javascripts/lib.js', 'vendor/assets/javascripts/transpiled.js', 'vendor/assets/javascripts/templates.js'],
|
||||
dest: 'vendor/assets/javascripts/compiled.js',
|
||||
},
|
||||
|
||||
@@ -117,14 +117,24 @@ module.exports = function(grunt) {
|
||||
babel: {
|
||||
options: {
|
||||
sourceMap: true,
|
||||
presets: ['es2015']
|
||||
presets: ['es2016']
|
||||
},
|
||||
dist: {
|
||||
files: {
|
||||
'vendor/assets/javascripts/app.js': 'vendor/assets/javascripts/app.js'
|
||||
'vendor/assets/javascripts/transpiled.js': 'vendor/assets/javascripts/app.js'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
browserify: {
|
||||
dist: {
|
||||
files: {
|
||||
'vendor/assets/javascripts/transpiled.js': 'vendor/assets/javascripts/transpiled.js'
|
||||
},
|
||||
options: {
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
ngAnnotate: {
|
||||
options: {
|
||||
@@ -156,6 +166,9 @@ module.exports = function(grunt) {
|
||||
grunt.loadNpmTasks('grunt-contrib-sass');
|
||||
grunt.loadNpmTasks('grunt-ng-annotate');
|
||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||
grunt.loadNpmTasks('grunt-babel');
|
||||
grunt.loadNpmTasks('grunt-browserify');
|
||||
|
||||
grunt.registerTask('default', ['haml', 'ngtemplates', 'sass', 'concat', 'babel', 'ngAnnotate', 'uglify']);
|
||||
grunt.registerTask('default', ['haml', 'ngtemplates', 'sass', 'concat:app', 'babel', 'browserify',
|
||||
'concat:lib', 'concat:dist', 'concat:css', 'ngAnnotate', 'uglify']);
|
||||
};
|
||||
|
||||
@@ -4,13 +4,32 @@ var Neeto = Neeto || {};
|
||||
|
||||
angular
|
||||
.module('app.frontend', [
|
||||
'app.services',
|
||||
'ui.router',
|
||||
'ng-token-auth',
|
||||
'restangular',
|
||||
'ipCookie',
|
||||
'oc.lazyLoad',
|
||||
'angularLazyImg',
|
||||
'ngDialog',
|
||||
'ngDialog'
|
||||
])
|
||||
.config(configureAuth);
|
||||
// Configure path to API
|
||||
.config(function (RestangularProvider, apiControllerProvider) {
|
||||
var url = apiControllerProvider.defaultServerURL();
|
||||
RestangularProvider.setBaseUrl(url);
|
||||
console.log(url);
|
||||
|
||||
RestangularProvider.setFullRequestInterceptor(function(element, operation, route, url, headers, params, httpConfig) {
|
||||
var token = localStorage.getItem("jwt");
|
||||
if(token) {
|
||||
headers = _.extend(headers, {Authorization: "Bearer " + localStorage.getItem("jwt")});
|
||||
}
|
||||
|
||||
return {
|
||||
element: element,
|
||||
params: params,
|
||||
headers: headers,
|
||||
httpConfig: httpConfig
|
||||
};
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('app.services', [
|
||||
'restangular'
|
||||
])
|
||||
|
||||
// Configure path to API
|
||||
.config(function (RestangularProvider, apiControllerProvider) {
|
||||
var url = apiControllerProvider.defaultServerURL();
|
||||
RestangularProvider.setBaseUrl(url);
|
||||
|
||||
RestangularProvider.setFullRequestInterceptor(function(element, operation, route, url, headers, params, httpConfig) {
|
||||
var token = localStorage.getItem("jwt");
|
||||
if(token) {
|
||||
headers = _.extend(headers, {Authorization: "Bearer " + localStorage.getItem("jwt")});
|
||||
}
|
||||
|
||||
return {
|
||||
element: element,
|
||||
params: params,
|
||||
headers: headers,
|
||||
httpConfig: httpConfig
|
||||
};
|
||||
});
|
||||
})
|
||||
|
||||
// Shared function for configure auth service. Can be overwritten.
|
||||
function configureAuth ($authProvider, apiControllerProvider) {
|
||||
var url = apiControllerProvider.defaultServerURL();
|
||||
$authProvider.configure([{
|
||||
default: {
|
||||
apiUrl: url,
|
||||
passwordResetSuccessUrl: window.location.protocol + '//' + window.location.host + '/auth/reset',
|
||||
}
|
||||
}]);
|
||||
}
|
||||
@@ -1,21 +1,13 @@
|
||||
angular.module('app.frontend')
|
||||
.controller('BaseCtrl', function ($rootScope, $scope, $state, $auth, apiController) {
|
||||
$rootScope.$on('auth:password-change-success', function(ev) {
|
||||
$state.go("home");
|
||||
});
|
||||
|
||||
$rootScope.$on('auth:password-change-error', function(ev, reason) {
|
||||
alert("Error: " + reason);
|
||||
});
|
||||
|
||||
$rootScope.resetPasswordSubmit = function() {
|
||||
var new_keys = Neeto.crypto.generateEncryptionKeysForUser($rootScope.resetData.password, $rootScope.resetData.email);
|
||||
var data = _.clone($rootScope.resetData);
|
||||
data.password = new_keys.pw;
|
||||
data.password_confirmation = new_keys.pw;
|
||||
$auth.updatePassword(data);
|
||||
apiController.setGk(new_keys.gk);
|
||||
}
|
||||
class BaseCtrl {
|
||||
constructor($rootScope, modelManager) {
|
||||
// $rootScope.resetPasswordSubmit = function() {
|
||||
// var new_keys = Neeto.crypto.generateEncryptionKeysForUser($rootScope.resetData.password, $rootScope.resetData.email);
|
||||
// var data = _.clone($rootScope.resetData);
|
||||
// data.password = new_keys.pw;
|
||||
// data.password_confirmation = new_keys.pw;
|
||||
// $auth.updatePassword(data);
|
||||
// apiController.setGk(new_keys.gk);
|
||||
// }
|
||||
|
||||
// var note = new Note();
|
||||
// note.content = {title: "hello", text: "world"};
|
||||
@@ -24,5 +16,7 @@ angular.module('app.frontend')
|
||||
// console.log("note json", JSON.stringify(note));
|
||||
//
|
||||
// console.log("Copy", _.cloneDeep(note));
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
angular.module('app.frontend').controller('BaseCtrl', BaseCtrl);
|
||||
|
||||
@@ -259,14 +259,14 @@ angular.module('app.frontend')
|
||||
a.click();
|
||||
}
|
||||
|
||||
apiController.shareNote(this.user, this.note, function(note){
|
||||
apiController.shareItem(this.user, this.note, function(note){
|
||||
openInNewTab(this.publicUrlForNote(note));
|
||||
}.bind(this))
|
||||
this.showMenu = false;
|
||||
}
|
||||
|
||||
this.unshareNote = function() {
|
||||
apiController.unshareNote(this.user, this.note, function(note){
|
||||
apiController.unshareItem(this.user, this.note, function(note){
|
||||
|
||||
})
|
||||
this.showMenu = false;
|
||||
|
||||
@@ -27,7 +27,7 @@ angular.module('app.frontend')
|
||||
}
|
||||
}
|
||||
})
|
||||
.controller('GroupsCtrl', function (apiController) {
|
||||
.controller('GroupsCtrl', function () {
|
||||
|
||||
var initialLoad = true;
|
||||
|
||||
@@ -54,8 +54,8 @@ angular.module('app.frontend')
|
||||
}
|
||||
|
||||
this.newGroup = new Group({notes : []});
|
||||
if(!this.user.id) {
|
||||
this.newGroup.id = Neeto.crypto.generateRandomKey()
|
||||
if(!this.user.uuid) {
|
||||
this.newGroup.uuid = Neeto.crypto.generateRandomKey()
|
||||
}
|
||||
this.selectedGroup = this.newGroup;
|
||||
this.editingGroup = this.newGroup;
|
||||
@@ -97,18 +97,6 @@ angular.module('app.frontend')
|
||||
}
|
||||
|
||||
this.handleDrop = function(e, newGroup, note) {
|
||||
if(this.selectedGroup.all) {
|
||||
// coming from all, remove from original group if applicable
|
||||
if(note.group_id) {
|
||||
var originalGroup = this.groups.filter(function(group){
|
||||
return group.id == note.group_id;
|
||||
})[0];
|
||||
_.remove(originalGroup.notes, note);
|
||||
}
|
||||
} else {
|
||||
_.remove(this.selectedGroup.notes, note);
|
||||
}
|
||||
|
||||
this.updateNoteGroup()(note, newGroup, this.selectedGroup);
|
||||
}.bind(this)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
angular.module('app.frontend')
|
||||
.controller('HomeCtrl', function ($scope, $rootScope, Restangular, $timeout, $state, $sce, $auth, apiController) {
|
||||
.controller('HomeCtrl', function ($scope, $rootScope, $timeout, apiController, modelManager) {
|
||||
$rootScope.bodyClass = "app-body-class";
|
||||
$rootScope.title = "Notes — Neeto, a secure code box for developers";
|
||||
$rootScope.description = "A secure code box for developers to store common commands and useful notes.";
|
||||
@@ -7,7 +7,7 @@ angular.module('app.frontend')
|
||||
var onUserSet = function() {
|
||||
|
||||
$scope.allGroup = new Group({name: "All", all: true});
|
||||
$scope.groups = $scope.defaultUser.groups;
|
||||
$scope.groups = modelManager.groups;
|
||||
|
||||
apiController.verifyEncryptionStatusOfAllItems($scope.defaultUser, function(success){
|
||||
|
||||
@@ -16,7 +16,8 @@ angular.module('app.frontend')
|
||||
|
||||
apiController.getCurrentUser(function(response){
|
||||
if(response && !response.errors) {
|
||||
$scope.defaultUser = new User(response.plain());
|
||||
$scope.defaultUser = new User(response);
|
||||
modelManager.items = response.items;
|
||||
$rootScope.title = "Notes — Neeto";
|
||||
onUserSet();
|
||||
} else {
|
||||
@@ -30,9 +31,7 @@ angular.module('app.frontend')
|
||||
*/
|
||||
|
||||
$scope.updateAllGroup = function() {
|
||||
var allNotes = Note.filterDummyNotes($scope.defaultUser.notes);
|
||||
$scope.defaultUser.notes = allNotes;
|
||||
$scope.allGroup.notes = allNotes;
|
||||
$scope.allGroup.notes = modelManager.filteredNotes;
|
||||
}
|
||||
|
||||
$scope.groupsWillMakeSelection = function(group) {
|
||||
@@ -49,11 +48,11 @@ angular.module('app.frontend')
|
||||
}
|
||||
|
||||
$scope.groupsAddNew = function(group) {
|
||||
$scope.defaultUser.groups.unshift(group);
|
||||
modelManager.addTag(group);
|
||||
}
|
||||
|
||||
$scope.groupsSave = function(group, callback) {
|
||||
apiController.saveItem($scope.defaultUser, group, callback);
|
||||
apiController.saveItems([group], callback);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -62,18 +61,13 @@ angular.module('app.frontend')
|
||||
*/
|
||||
$scope.groupsUpdateNoteGroup = function(noteCopy, newGroup, oldGroup) {
|
||||
|
||||
var originalNote = _.find($scope.defaultUser.notes, {id: noteCopy.id});
|
||||
|
||||
$scope.defaultUser.itemManager.removeReferencesBetweenItems(oldGroup, originalNote);
|
||||
|
||||
var originalNote = _.find($scope.defaultUser.notes, {uuid: noteCopy.uuid});
|
||||
modelManager.removeTagFromNote(oldGroup, originalNote);
|
||||
if(!newGroup.all) {
|
||||
$scope.defaultUser.itemManager.createReferencesBetweenItems(newGroup, originalNote);
|
||||
newGroup.updateReferencesLocalMapping();
|
||||
modelManager.addTagToNote(newGroup, originalNote);
|
||||
}
|
||||
|
||||
apiController.saveBatchItems($scope.defaultUser, [originalNote, newGroup, oldGroup], function(){
|
||||
|
||||
});
|
||||
apiController.saveDirtyItems(function(){});
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -88,7 +82,7 @@ angular.module('app.frontend')
|
||||
// force scope groups to update on sub directives
|
||||
$scope.groups = [];
|
||||
$timeout(function(){
|
||||
$scope.groups = $scope.defaultUser.groups;
|
||||
$scope.groups = modelManager.groups;
|
||||
})
|
||||
});
|
||||
} else {
|
||||
@@ -106,12 +100,10 @@ angular.module('app.frontend')
|
||||
note.id = Neeto.crypto.generateRandomKey();
|
||||
}
|
||||
|
||||
$scope.defaultUser.notes.unshift(note);
|
||||
modelManager.addNote(note);
|
||||
|
||||
if(!$scope.selectedGroup.all) {
|
||||
$scope.selectedGroup.notes.unshift(note);
|
||||
note.group_id = $scope.selectedGroup.id;
|
||||
|
||||
modelManager.addTagToNote($scope.selectedGroup, note);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,11 +112,8 @@ angular.module('app.frontend')
|
||||
*/
|
||||
|
||||
$scope.saveNote = function(note, callback) {
|
||||
apiController.saveNote($scope.defaultUser, note, function(){
|
||||
// add to All notes if it doesnt exist
|
||||
if(!_.find($scope.defaultUser.notes, {id: note.id})) {
|
||||
$scope.defaultUser.notes.unshift(note);
|
||||
}
|
||||
apiController.saveItems([note], function(){
|
||||
modelManager.addNote(note);
|
||||
note.hasChanges = false;
|
||||
|
||||
if(callback) {
|
||||
@@ -134,15 +123,8 @@ angular.module('app.frontend')
|
||||
}
|
||||
|
||||
$scope.deleteNote = function(note) {
|
||||
_.remove($scope.defaultUser.notes, note);
|
||||
if($scope.selectedGroup.all && note.group_id) {
|
||||
var originalGroup = _.find($scope.groups, {id: note.group_id});
|
||||
if(originalGroup) {
|
||||
_.remove(originalGroup.notes, note);
|
||||
}
|
||||
} else {
|
||||
_.remove($scope.selectedGroup.notes, note);
|
||||
}
|
||||
|
||||
modelManager.deleteNote(note);
|
||||
|
||||
if(note == $scope.selectedNote) {
|
||||
$scope.selectedNote = null;
|
||||
@@ -152,8 +134,8 @@ angular.module('app.frontend')
|
||||
return;
|
||||
}
|
||||
|
||||
apiController.deleteNote($scope.defaultUser, note, function(success){
|
||||
})
|
||||
apiController.deleteItem($scope.defaultUser, note, function(success){})
|
||||
apiController.saveDirtyItems(function(){});
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -77,7 +77,7 @@ angular.module('app.frontend')
|
||||
}
|
||||
|
||||
var callback = function(username) {
|
||||
apiController.shareGroup(this.user, this.group, function(response){
|
||||
apiController.shareItem(this.user, this.group, function(response){
|
||||
})
|
||||
}.bind(this);
|
||||
|
||||
@@ -99,7 +99,7 @@ angular.module('app.frontend')
|
||||
|
||||
this.selectedGroupUnshare = function() {
|
||||
this.showMenu = false;
|
||||
apiController.unshareGroup(this.user, this.group, function(response){
|
||||
apiController.unshareItem(this.user, this.group, function(response){
|
||||
|
||||
})
|
||||
}
|
||||
@@ -138,7 +138,7 @@ angular.module('app.frontend')
|
||||
var title = "New Note" + (this.notes ? (" " + (this.notes.length + 1)) : "");
|
||||
this.newNote = new Note({dummy: true});
|
||||
this.newNote.content.title = title;
|
||||
this.newNote.group = this.group;
|
||||
modelManager.addTagToNote(this.group, this.newNote);
|
||||
this.selectNote(this.newNote);
|
||||
this.addNew()(this.newNote);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
class Note extends Item {
|
||||
class Item {
|
||||
|
||||
constructor(json_obj) {
|
||||
var content;
|
||||
|
||||
@@ -24,40 +25,37 @@ class Note extends Item {
|
||||
enumerable: true,
|
||||
});
|
||||
|
||||
_.merge(this, json_obj);
|
||||
|
||||
this.setContentRaw = function(rawContent) {
|
||||
content = rawContent;
|
||||
}
|
||||
|
||||
_.merge(this, json_obj);
|
||||
|
||||
if(!this.content) {
|
||||
this.content = {title: "", text: ""};
|
||||
}
|
||||
}
|
||||
|
||||
filterDummyNotes(notes) {
|
||||
var filtered = notes.filter(function(note){return note.dummy == false || note.dummy == null});
|
||||
return filtered;
|
||||
referencesMatchingContentType(contentType) {
|
||||
return this.references.filter(function(reference){
|
||||
return reference.content_type == content_type;
|
||||
});
|
||||
}
|
||||
|
||||
updateReferencesLocalMapping() {
|
||||
super.updateReferencesLocalMapping();
|
||||
this.groups = this.referencesMatchingContentType("Group");
|
||||
// should be overriden to manage local properties
|
||||
}
|
||||
|
||||
get hasOnePublicGroup() {
|
||||
var hasPublicGroup = false;
|
||||
this.groups.forEach(function(group){
|
||||
if(group.isPublic()) {
|
||||
hasPublicGroup = true;
|
||||
return;
|
||||
}
|
||||
})
|
||||
|
||||
return hasPublicGroup;
|
||||
/* Returns true if note is shared individually or via group */
|
||||
isPublic() {
|
||||
return this.presentation;
|
||||
}
|
||||
|
||||
function isPublic() {
|
||||
return super.isPublic() || this.hasOnePublicGroup;
|
||||
isEncrypted() {
|
||||
return this.encryptionEnabled() && typeof this.content === 'string' ? true : false;
|
||||
}
|
||||
|
||||
encryptionEnabled() {
|
||||
return this.loc_eek;
|
||||
}
|
||||
|
||||
presentationURL() {
|
||||
return this.presentation.url;
|
||||
}
|
||||
}
|
||||
36
app/assets/javascripts/app/frontend/models/app/note.js
Normal file
36
app/assets/javascripts/app/frontend/models/app/note.js
Normal file
@@ -0,0 +1,36 @@
|
||||
class Note extends Item {
|
||||
|
||||
constructor(json_obj) {
|
||||
|
||||
super(json_obj);
|
||||
|
||||
if(!this.content) {
|
||||
this.content = {title: "", text: ""};
|
||||
}
|
||||
}
|
||||
|
||||
filterDummyNotes(notes) {
|
||||
var filtered = notes.filter(function(note){return note.dummy == false || note.dummy == null});
|
||||
return filtered;
|
||||
}
|
||||
|
||||
get hasOnePublicGroup() {
|
||||
var hasPublicGroup = false;
|
||||
this.groups.forEach(function(group){
|
||||
if(group.isPublic()) {
|
||||
hasPublicGroup = true;
|
||||
return;
|
||||
}
|
||||
})
|
||||
|
||||
return hasPublicGroup;
|
||||
}
|
||||
|
||||
isPublic() {
|
||||
return super.isPublic() || this.hasOnePublicGroup;
|
||||
}
|
||||
|
||||
get content_type() {
|
||||
return "Note";
|
||||
}
|
||||
}
|
||||
10
app/assets/javascripts/app/frontend/models/app/tag.js
Normal file
10
app/assets/javascripts/app/frontend/models/app/tag.js
Normal file
@@ -0,0 +1,10 @@
|
||||
class Tag extends Item {
|
||||
|
||||
constructor(json_obj) {
|
||||
super(json_obj);
|
||||
}
|
||||
|
||||
get content_type() {
|
||||
return "Tag";
|
||||
}
|
||||
}
|
||||
5
app/assets/javascripts/app/frontend/models/app/user.js
Normal file
5
app/assets/javascripts/app/frontend/models/app/user.js
Normal file
@@ -0,0 +1,5 @@
|
||||
class User {
|
||||
constructor(json_obj) {
|
||||
_.merge(this, json_obj);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
class Group extends Item {
|
||||
constructor(json_obj) {
|
||||
_.merge(this, json_obj);
|
||||
}
|
||||
|
||||
updateReferencesLocalMapping() {
|
||||
super.updateReferencesLocalMapping();
|
||||
this.notes = this.referencesMatchingContentType("Note");
|
||||
this.notes.sort(function(a,b){
|
||||
return new Date(b.created_at) - new Date(a.created_at);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
class Item {
|
||||
|
||||
referencesMatchingContentType(contentType) {
|
||||
return this.references.filter(function(reference){
|
||||
return reference.content_type == content_type;
|
||||
});
|
||||
}
|
||||
|
||||
updateReferencesLocalMapping() {
|
||||
// should be overriden to manage local properties
|
||||
}
|
||||
|
||||
/* Returns true if note is shared individually or via group */
|
||||
isPublic() {
|
||||
return this.presentation;
|
||||
}
|
||||
|
||||
isEncrypted() {
|
||||
return this.encryptionEnabled() && typeof this.content === 'string' ? true : false;
|
||||
}
|
||||
|
||||
encryptionEnabled() {
|
||||
return this.loc_eek;
|
||||
}
|
||||
|
||||
presentationURL() {
|
||||
return this.presentation.url;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
class User {
|
||||
constructor(json_obj) {
|
||||
_.merge(this, json_obj);
|
||||
|
||||
this.itemManager = new ItemManager();
|
||||
this.itemManager.items = this.items;
|
||||
this.items = null;
|
||||
|
||||
this.notes = _.map(this.itemManager.itemsForContentType("Note"), function(json_obj) {
|
||||
return new Note(json_obj);
|
||||
})
|
||||
|
||||
this.groups = _.map(this.itemManager.itemsForContentType("Group"), function(json_obj) {
|
||||
var group = Group(json_obj);
|
||||
group.updateReferencesLocalMapping();
|
||||
return group;
|
||||
})
|
||||
}
|
||||
|
||||
filteredNotes() {
|
||||
return Note.filterDummyNotes(this.notes);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module('app.services')
|
||||
angular.module('app.frontend')
|
||||
.provider('apiController', function () {
|
||||
|
||||
function domainName() {
|
||||
@@ -59,7 +59,7 @@ angular.module('app.services')
|
||||
return;
|
||||
}
|
||||
Restangular.one("users/current").get().then(function(response){
|
||||
callback(response);
|
||||
callback(response.plain());
|
||||
})
|
||||
}
|
||||
|
||||
@@ -171,37 +171,26 @@ angular.module('app.services')
|
||||
Items
|
||||
*/
|
||||
|
||||
this.saveBatchItems = function(user, items, callback) {
|
||||
var request = Restangular.one("users", user.uuid).one("items/batch_update");
|
||||
request.items = _.map(items, function(item){
|
||||
return this.createRequestParamsFromItem(item, user);
|
||||
}.bind(this));
|
||||
request.put().then(function(response){
|
||||
var success = response.plain().success;
|
||||
callback(success);
|
||||
this.saveDirtyItems = function(callback) {
|
||||
var dirtyItems = modelManager.dirtyItems;
|
||||
|
||||
this.saveItems(dirtyItems, function(response){
|
||||
modelManager.clearDirtyItems();
|
||||
})
|
||||
}
|
||||
|
||||
this.saveItem = function(user, item, callback) {
|
||||
if(!user.id) {
|
||||
this.writeUserToLocalStorage(user);
|
||||
callback(item);
|
||||
return;
|
||||
}
|
||||
this.saveItems = function(items, callback) {
|
||||
var request = Restangular.one("users", user.uuid).one("items");
|
||||
request.items = _.map(items, function(item){
|
||||
return this.createRequestParamsFromItem(item, user);
|
||||
}.bind(this));
|
||||
|
||||
var params = this.createRequestParamsForItem(item, user);
|
||||
|
||||
var request = Restangular.one("users", user.uuid).one("item", item.uuid);
|
||||
_.merge(request, params);
|
||||
request.customOperation(request.uuid ? "put" : "post")
|
||||
.then(function(response) {
|
||||
var responseObject = response.plain();
|
||||
responseObject.content = item.content;
|
||||
_.merge(item, responseObject);
|
||||
callback(item);
|
||||
})
|
||||
.catch(function(response){
|
||||
callback(null);
|
||||
request.post().then(function(response) {
|
||||
var savedItems = response.items;
|
||||
items.forEach(function(item){
|
||||
_.merge(item, _.find(savedItems, {uuid: item.uuid}));
|
||||
})
|
||||
callback(response);
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
angular
|
||||
.module('app.services')
|
||||
.module('app.frontend')
|
||||
.directive('mbAutofocus', ['$timeout', function($timeout) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
angular
|
||||
.module('app.services')
|
||||
.module('app.frontend')
|
||||
.directive('draggable', function() {
|
||||
return {
|
||||
scope: {
|
||||
@@ -35,7 +35,7 @@ angular
|
||||
});
|
||||
|
||||
angular
|
||||
.module('app.services')
|
||||
.module('app.frontend')
|
||||
.directive('droppable', function() {
|
||||
return {
|
||||
scope: {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
angular
|
||||
.module('app.services')
|
||||
.module('app.frontend')
|
||||
.directive('fileChange', function() {
|
||||
return {
|
||||
restrict: 'A',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
angular
|
||||
.module('app.services')
|
||||
.module('app.frontend')
|
||||
.directive('lowercase', function() {
|
||||
return {
|
||||
require: 'ngModel',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
angular
|
||||
.module('app.services')
|
||||
.module('app.frontend')
|
||||
.directive('selectOnClick', ['$window', function ($window) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
angular
|
||||
.module('app.services')
|
||||
.module('app.frontend')
|
||||
.directive('note', function($timeout) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
|
||||
angular
|
||||
.module('app.services').directive('typewrite', ['$timeout', function ($timeout) {
|
||||
.module('app.frontend').directive('typewrite', ['$timeout', function ($timeout) {
|
||||
function linkFunction($scope, $element, $attrs) {
|
||||
var timer = null,
|
||||
initialDelay = $attrs.initialDelay ? getTypeDelay($attrs.initialDelay) : 200,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
class ItemManager() {
|
||||
class ItemManager {
|
||||
|
||||
set items(items) {
|
||||
this.items = items;
|
||||
@@ -27,8 +27,8 @@ class ItemManager() {
|
||||
// returns dirty item references that need saving
|
||||
deleteItem(item) {
|
||||
_.remove(this.items, item);
|
||||
item.references.forEach(function(reference){
|
||||
removeReferencesFromItem(reference, item);
|
||||
item.references.forEach(function(referencedItem){
|
||||
removeReferencesBetweenItems(referencedItem, item);
|
||||
})
|
||||
|
||||
return item.references;
|
||||
@@ -40,16 +40,11 @@ class ItemManager() {
|
||||
return [itemOne, itemTwo];
|
||||
}
|
||||
|
||||
removeReferencesBetweenItems(itemOne, itemTwo) {
|
||||
itemOne.references.push(itemTwo);
|
||||
itemTwo.references.push(itemOne);
|
||||
return [itemOne, itemTwo];
|
||||
}
|
||||
|
||||
createReferencesBetweenItems(itemOne, itemTwo) {
|
||||
itemOne.references.push(itemTwo);
|
||||
itemTwo.references.push(itemOne);
|
||||
return [itemOne, itemTwo];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
angular.module('app.frontend').service('itemManager', ItemManager);
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module('app.services')
|
||||
angular.module('app.frontend')
|
||||
.service('markdownRenderer', function ($sce) {
|
||||
|
||||
marked.setOptions({
|
||||
|
||||
85
app/assets/javascripts/app/services/modelManager.js
Normal file
85
app/assets/javascripts/app/services/modelManager.js
Normal file
@@ -0,0 +1,85 @@
|
||||
class ModelManager extends ItemManager {
|
||||
|
||||
set items(items) {
|
||||
super.items = items;
|
||||
|
||||
this.notes = _.map(this.items.itemsForContentType("Note"), function(json_obj) {
|
||||
return new Note(json_obj);
|
||||
})
|
||||
|
||||
this.groups = _.map(this.items.itemsForContentType("Group"), function(json_obj) {
|
||||
var group = Group(json_obj);
|
||||
group.updateReferencesLocalMapping();
|
||||
return group;
|
||||
})
|
||||
}
|
||||
|
||||
addDirtyItems(items) {
|
||||
if(this.dirtyItems) {
|
||||
this.dirtyItems = [];
|
||||
}
|
||||
|
||||
this.dirtyItems.concat(items);
|
||||
}
|
||||
|
||||
get dirtyItems() {
|
||||
return this.dirtyItems || [];
|
||||
}
|
||||
|
||||
get filteredNotes() {
|
||||
return Note.filterDummyNotes(this.notes);
|
||||
}
|
||||
|
||||
clearDirtyItems() {
|
||||
this.dirtyItems = [];
|
||||
}
|
||||
|
||||
addNote(note) {
|
||||
if(!_.find(this.notes, {uuid: note.uuid})) {
|
||||
this.notes.unshift(note);
|
||||
}
|
||||
}
|
||||
|
||||
addTag(tag) {
|
||||
this.tags.unshift(tag);
|
||||
}
|
||||
|
||||
addTagToNote(tag, note) {
|
||||
var dirty = this.createReferencesBetweenItems(tag, note);
|
||||
this.refreshRelationshipsForTag(tag);
|
||||
this.refreshRelationshipsForNote(note);
|
||||
this.addDirtyItems(dirty);
|
||||
}
|
||||
|
||||
refreshRelationshipsForTag(tag) {
|
||||
tag.notes = tag.referencesMatchingContentType("Note");
|
||||
tag.notes.sort(function(a,b){
|
||||
return new Date(b.created_at) - new Date(a.created_at);
|
||||
});
|
||||
}
|
||||
|
||||
refreshRelationshipsForNote(note) {
|
||||
note.groups = note.referencesMatchingContentType("Group");
|
||||
}
|
||||
|
||||
removeTagFromNote(tag, note) {
|
||||
var dirty = this.removeReferencesBetweenItems(tag, note);
|
||||
this.addDirtyItems(dirty);
|
||||
}
|
||||
|
||||
deleteNote(note) {
|
||||
var dirty = this.deleteItem(note);
|
||||
this.addDirtyItems(dirty);
|
||||
}
|
||||
|
||||
deleteTag(tag) {
|
||||
var dirty = this.deleteItem(tag);
|
||||
this.addDirtyItems(dirty);
|
||||
}
|
||||
|
||||
filteredNotes() {
|
||||
return Note.filterDummyNotes(this.notes);
|
||||
}
|
||||
}
|
||||
|
||||
angular.module('app.frontend').service('modelManager', ModelManager);
|
||||
@@ -1,4 +1,4 @@
|
||||
angular.module('app.services')
|
||||
angular.module('app.frontend')
|
||||
.service('serverSideValidation', function ($sce) {
|
||||
// Show validation errors in form.
|
||||
this.showErrors = function (formErrors, form) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//= require app/app.services.js
|
||||
//= require app/app.frontend.js
|
||||
//= require_tree ./app/services
|
||||
|
||||
//= require app/app.frontend.js
|
||||
|
||||
@@ -2,10 +2,14 @@
|
||||
"name": "neeto",
|
||||
"version": "1.0.0",
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.18.0",
|
||||
"babel-preset-env": "^1.1.1",
|
||||
"babel-preset-es2015": "^6.18.0",
|
||||
"babel-preset-es2016": "^6.16.0",
|
||||
"grunt": "^1.0.1",
|
||||
"grunt-angular-templates": "^1.1.0",
|
||||
"grunt-babel": "^6.0.0",
|
||||
"grunt-browserify": "^5.0.0",
|
||||
"grunt-contrib-concat": "^1.0.1",
|
||||
"grunt-contrib-cssmin": "^1.0.2",
|
||||
"grunt-contrib-jshint": "~0.10.0",
|
||||
|
||||
1
vendor/assets/javascripts/app.js.map
vendored
Normal file
1
vendor/assets/javascripts/app.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
1
vendor/assets/javascripts/compiled.js.map
vendored
Normal file
1
vendor/assets/javascripts/compiled.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2308
vendor/assets/javascripts/transpiled.js
vendored
Normal file
2308
vendor/assets/javascripts/transpiled.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
vendor/assets/javascripts/transpiled.js.map
vendored
Normal file
1
vendor/assets/javascripts/transpiled.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user