es6
This commit is contained in:
27
Gruntfile.js
27
Gruntfile.js
@@ -13,7 +13,7 @@ module.exports = function(grunt) {
|
|||||||
|
|
||||||
js: {
|
js: {
|
||||||
files: ['app/assets/javascripts/**/*.js'],
|
files: ['app/assets/javascripts/**/*.js'],
|
||||||
tasks: ['concat', 'babel'],
|
tasks: [ 'concat:app', 'babel', 'browserify', 'concat:dist'],
|
||||||
options: {
|
options: {
|
||||||
spawn: false,
|
spawn: false,
|
||||||
},
|
},
|
||||||
@@ -21,7 +21,7 @@ module.exports = function(grunt) {
|
|||||||
|
|
||||||
css: {
|
css: {
|
||||||
files: ['app/assets/stylesheets/**/*.scss'],
|
files: ['app/assets/stylesheets/**/*.scss'],
|
||||||
tasks: ['sass', 'concat'],
|
tasks: ['sass', 'concat:css'],
|
||||||
options: {
|
options: {
|
||||||
spawn: false,
|
spawn: false,
|
||||||
},
|
},
|
||||||
@@ -73,7 +73,7 @@ module.exports = function(grunt) {
|
|||||||
'app/assets/javascripts/app/*.js',
|
'app/assets/javascripts/app/*.js',
|
||||||
'app/assets/javascripts/app/frontend/*.js',
|
'app/assets/javascripts/app/frontend/*.js',
|
||||||
'app/assets/javascripts/app/frontend/controllers/*.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/*.js',
|
||||||
'app/assets/javascripts/app/services/directives/*.js',
|
'app/assets/javascripts/app/services/directives/*.js',
|
||||||
'app/assets/javascripts/app/services/helpers/*.js',
|
'app/assets/javascripts/app/services/helpers/*.js',
|
||||||
@@ -99,7 +99,7 @@ module.exports = function(grunt) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
dist: {
|
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',
|
dest: 'vendor/assets/javascripts/compiled.js',
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -117,14 +117,24 @@ module.exports = function(grunt) {
|
|||||||
babel: {
|
babel: {
|
||||||
options: {
|
options: {
|
||||||
sourceMap: true,
|
sourceMap: true,
|
||||||
presets: ['es2015']
|
presets: ['es2016']
|
||||||
},
|
},
|
||||||
dist: {
|
dist: {
|
||||||
files: {
|
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: {
|
ngAnnotate: {
|
||||||
options: {
|
options: {
|
||||||
@@ -156,6 +166,9 @@ module.exports = function(grunt) {
|
|||||||
grunt.loadNpmTasks('grunt-contrib-sass');
|
grunt.loadNpmTasks('grunt-contrib-sass');
|
||||||
grunt.loadNpmTasks('grunt-ng-annotate');
|
grunt.loadNpmTasks('grunt-ng-annotate');
|
||||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
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
|
angular
|
||||||
.module('app.frontend', [
|
.module('app.frontend', [
|
||||||
'app.services',
|
|
||||||
'ui.router',
|
'ui.router',
|
||||||
'ng-token-auth',
|
'ng-token-auth',
|
||||||
'restangular',
|
'restangular',
|
||||||
'ipCookie',
|
'ipCookie',
|
||||||
'oc.lazyLoad',
|
'oc.lazyLoad',
|
||||||
'angularLazyImg',
|
'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')
|
class BaseCtrl {
|
||||||
.controller('BaseCtrl', function ($rootScope, $scope, $state, $auth, apiController) {
|
constructor($rootScope, modelManager) {
|
||||||
$rootScope.$on('auth:password-change-success', function(ev) {
|
// $rootScope.resetPasswordSubmit = function() {
|
||||||
$state.go("home");
|
// var new_keys = Neeto.crypto.generateEncryptionKeysForUser($rootScope.resetData.password, $rootScope.resetData.email);
|
||||||
});
|
// var data = _.clone($rootScope.resetData);
|
||||||
|
// data.password = new_keys.pw;
|
||||||
$rootScope.$on('auth:password-change-error', function(ev, reason) {
|
// data.password_confirmation = new_keys.pw;
|
||||||
alert("Error: " + reason);
|
// $auth.updatePassword(data);
|
||||||
});
|
// apiController.setGk(new_keys.gk);
|
||||||
|
// }
|
||||||
$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();
|
// var note = new Note();
|
||||||
// note.content = {title: "hello", text: "world"};
|
// note.content = {title: "hello", text: "world"};
|
||||||
@@ -24,5 +16,7 @@ angular.module('app.frontend')
|
|||||||
// console.log("note json", JSON.stringify(note));
|
// console.log("note json", JSON.stringify(note));
|
||||||
//
|
//
|
||||||
// console.log("Copy", _.cloneDeep(note));
|
// console.log("Copy", _.cloneDeep(note));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
});
|
angular.module('app.frontend').controller('BaseCtrl', BaseCtrl);
|
||||||
|
|||||||
@@ -259,14 +259,14 @@ angular.module('app.frontend')
|
|||||||
a.click();
|
a.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
apiController.shareNote(this.user, this.note, function(note){
|
apiController.shareItem(this.user, this.note, function(note){
|
||||||
openInNewTab(this.publicUrlForNote(note));
|
openInNewTab(this.publicUrlForNote(note));
|
||||||
}.bind(this))
|
}.bind(this))
|
||||||
this.showMenu = false;
|
this.showMenu = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.unshareNote = function() {
|
this.unshareNote = function() {
|
||||||
apiController.unshareNote(this.user, this.note, function(note){
|
apiController.unshareItem(this.user, this.note, function(note){
|
||||||
|
|
||||||
})
|
})
|
||||||
this.showMenu = false;
|
this.showMenu = false;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ angular.module('app.frontend')
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.controller('GroupsCtrl', function (apiController) {
|
.controller('GroupsCtrl', function () {
|
||||||
|
|
||||||
var initialLoad = true;
|
var initialLoad = true;
|
||||||
|
|
||||||
@@ -54,8 +54,8 @@ angular.module('app.frontend')
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.newGroup = new Group({notes : []});
|
this.newGroup = new Group({notes : []});
|
||||||
if(!this.user.id) {
|
if(!this.user.uuid) {
|
||||||
this.newGroup.id = Neeto.crypto.generateRandomKey()
|
this.newGroup.uuid = Neeto.crypto.generateRandomKey()
|
||||||
}
|
}
|
||||||
this.selectedGroup = this.newGroup;
|
this.selectedGroup = this.newGroup;
|
||||||
this.editingGroup = this.newGroup;
|
this.editingGroup = this.newGroup;
|
||||||
@@ -97,18 +97,6 @@ angular.module('app.frontend')
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.handleDrop = function(e, newGroup, note) {
|
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);
|
this.updateNoteGroup()(note, newGroup, this.selectedGroup);
|
||||||
}.bind(this)
|
}.bind(this)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
angular.module('app.frontend')
|
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.bodyClass = "app-body-class";
|
||||||
$rootScope.title = "Notes — Neeto, a secure code box for developers";
|
$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.";
|
$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() {
|
var onUserSet = function() {
|
||||||
|
|
||||||
$scope.allGroup = new Group({name: "All", all: true});
|
$scope.allGroup = new Group({name: "All", all: true});
|
||||||
$scope.groups = $scope.defaultUser.groups;
|
$scope.groups = modelManager.groups;
|
||||||
|
|
||||||
apiController.verifyEncryptionStatusOfAllItems($scope.defaultUser, function(success){
|
apiController.verifyEncryptionStatusOfAllItems($scope.defaultUser, function(success){
|
||||||
|
|
||||||
@@ -16,7 +16,8 @@ angular.module('app.frontend')
|
|||||||
|
|
||||||
apiController.getCurrentUser(function(response){
|
apiController.getCurrentUser(function(response){
|
||||||
if(response && !response.errors) {
|
if(response && !response.errors) {
|
||||||
$scope.defaultUser = new User(response.plain());
|
$scope.defaultUser = new User(response);
|
||||||
|
modelManager.items = response.items;
|
||||||
$rootScope.title = "Notes — Neeto";
|
$rootScope.title = "Notes — Neeto";
|
||||||
onUserSet();
|
onUserSet();
|
||||||
} else {
|
} else {
|
||||||
@@ -30,9 +31,7 @@ angular.module('app.frontend')
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
$scope.updateAllGroup = function() {
|
$scope.updateAllGroup = function() {
|
||||||
var allNotes = Note.filterDummyNotes($scope.defaultUser.notes);
|
$scope.allGroup.notes = modelManager.filteredNotes;
|
||||||
$scope.defaultUser.notes = allNotes;
|
|
||||||
$scope.allGroup.notes = allNotes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.groupsWillMakeSelection = function(group) {
|
$scope.groupsWillMakeSelection = function(group) {
|
||||||
@@ -49,11 +48,11 @@ angular.module('app.frontend')
|
|||||||
}
|
}
|
||||||
|
|
||||||
$scope.groupsAddNew = function(group) {
|
$scope.groupsAddNew = function(group) {
|
||||||
$scope.defaultUser.groups.unshift(group);
|
modelManager.addTag(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.groupsSave = function(group, callback) {
|
$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) {
|
$scope.groupsUpdateNoteGroup = function(noteCopy, newGroup, oldGroup) {
|
||||||
|
|
||||||
var originalNote = _.find($scope.defaultUser.notes, {id: noteCopy.id});
|
var originalNote = _.find($scope.defaultUser.notes, {uuid: noteCopy.uuid});
|
||||||
|
modelManager.removeTagFromNote(oldGroup, originalNote);
|
||||||
$scope.defaultUser.itemManager.removeReferencesBetweenItems(oldGroup, originalNote);
|
|
||||||
|
|
||||||
if(!newGroup.all) {
|
if(!newGroup.all) {
|
||||||
$scope.defaultUser.itemManager.createReferencesBetweenItems(newGroup, originalNote);
|
modelManager.addTagToNote(newGroup, originalNote);
|
||||||
newGroup.updateReferencesLocalMapping();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
// force scope groups to update on sub directives
|
||||||
$scope.groups = [];
|
$scope.groups = [];
|
||||||
$timeout(function(){
|
$timeout(function(){
|
||||||
$scope.groups = $scope.defaultUser.groups;
|
$scope.groups = modelManager.groups;
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -106,12 +100,10 @@ angular.module('app.frontend')
|
|||||||
note.id = Neeto.crypto.generateRandomKey();
|
note.id = Neeto.crypto.generateRandomKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.defaultUser.notes.unshift(note);
|
modelManager.addNote(note);
|
||||||
|
|
||||||
if(!$scope.selectedGroup.all) {
|
if(!$scope.selectedGroup.all) {
|
||||||
$scope.selectedGroup.notes.unshift(note);
|
modelManager.addTagToNote($scope.selectedGroup, note);
|
||||||
note.group_id = $scope.selectedGroup.id;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,11 +112,8 @@ angular.module('app.frontend')
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
$scope.saveNote = function(note, callback) {
|
$scope.saveNote = function(note, callback) {
|
||||||
apiController.saveNote($scope.defaultUser, note, function(){
|
apiController.saveItems([note], function(){
|
||||||
// add to All notes if it doesnt exist
|
modelManager.addNote(note);
|
||||||
if(!_.find($scope.defaultUser.notes, {id: note.id})) {
|
|
||||||
$scope.defaultUser.notes.unshift(note);
|
|
||||||
}
|
|
||||||
note.hasChanges = false;
|
note.hasChanges = false;
|
||||||
|
|
||||||
if(callback) {
|
if(callback) {
|
||||||
@@ -134,15 +123,8 @@ angular.module('app.frontend')
|
|||||||
}
|
}
|
||||||
|
|
||||||
$scope.deleteNote = function(note) {
|
$scope.deleteNote = function(note) {
|
||||||
_.remove($scope.defaultUser.notes, note);
|
|
||||||
if($scope.selectedGroup.all && note.group_id) {
|
modelManager.deleteNote(note);
|
||||||
var originalGroup = _.find($scope.groups, {id: note.group_id});
|
|
||||||
if(originalGroup) {
|
|
||||||
_.remove(originalGroup.notes, note);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_.remove($scope.selectedGroup.notes, note);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(note == $scope.selectedNote) {
|
if(note == $scope.selectedNote) {
|
||||||
$scope.selectedNote = null;
|
$scope.selectedNote = null;
|
||||||
@@ -152,8 +134,8 @@ angular.module('app.frontend')
|
|||||||
return;
|
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) {
|
var callback = function(username) {
|
||||||
apiController.shareGroup(this.user, this.group, function(response){
|
apiController.shareItem(this.user, this.group, function(response){
|
||||||
})
|
})
|
||||||
}.bind(this);
|
}.bind(this);
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ angular.module('app.frontend')
|
|||||||
|
|
||||||
this.selectedGroupUnshare = function() {
|
this.selectedGroupUnshare = function() {
|
||||||
this.showMenu = false;
|
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)) : "");
|
var title = "New Note" + (this.notes ? (" " + (this.notes.length + 1)) : "");
|
||||||
this.newNote = new Note({dummy: true});
|
this.newNote = new Note({dummy: true});
|
||||||
this.newNote.content.title = title;
|
this.newNote.content.title = title;
|
||||||
this.newNote.group = this.group;
|
modelManager.addTagToNote(this.group, this.newNote);
|
||||||
this.selectNote(this.newNote);
|
this.selectNote(this.newNote);
|
||||||
this.addNew()(this.newNote);
|
this.addNew()(this.newNote);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
class Note extends Item {
|
class Item {
|
||||||
|
|
||||||
constructor(json_obj) {
|
constructor(json_obj) {
|
||||||
var content;
|
var content;
|
||||||
|
|
||||||
@@ -24,40 +25,37 @@ class Note extends Item {
|
|||||||
enumerable: true,
|
enumerable: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_.merge(this, json_obj);
|
||||||
|
|
||||||
this.setContentRaw = function(rawContent) {
|
this.setContentRaw = function(rawContent) {
|
||||||
content = rawContent;
|
content = rawContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
_.merge(this, json_obj);
|
|
||||||
|
|
||||||
if(!this.content) {
|
|
||||||
this.content = {title: "", text: ""};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
filterDummyNotes(notes) {
|
referencesMatchingContentType(contentType) {
|
||||||
var filtered = notes.filter(function(note){return note.dummy == false || note.dummy == null});
|
return this.references.filter(function(reference){
|
||||||
return filtered;
|
return reference.content_type == content_type;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateReferencesLocalMapping() {
|
updateReferencesLocalMapping() {
|
||||||
super.updateReferencesLocalMapping();
|
// should be overriden to manage local properties
|
||||||
this.groups = this.referencesMatchingContentType("Group");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get hasOnePublicGroup() {
|
/* Returns true if note is shared individually or via group */
|
||||||
var hasPublicGroup = false;
|
isPublic() {
|
||||||
this.groups.forEach(function(group){
|
return this.presentation;
|
||||||
if(group.isPublic()) {
|
|
||||||
hasPublicGroup = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return hasPublicGroup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPublic() {
|
isEncrypted() {
|
||||||
return super.isPublic() || this.hasOnePublicGroup;
|
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 () {
|
.provider('apiController', function () {
|
||||||
|
|
||||||
function domainName() {
|
function domainName() {
|
||||||
@@ -59,7 +59,7 @@ angular.module('app.services')
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Restangular.one("users/current").get().then(function(response){
|
Restangular.one("users/current").get().then(function(response){
|
||||||
callback(response);
|
callback(response.plain());
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,37 +171,26 @@ angular.module('app.services')
|
|||||||
Items
|
Items
|
||||||
*/
|
*/
|
||||||
|
|
||||||
this.saveBatchItems = function(user, items, callback) {
|
this.saveDirtyItems = function(callback) {
|
||||||
var request = Restangular.one("users", user.uuid).one("items/batch_update");
|
var dirtyItems = modelManager.dirtyItems;
|
||||||
|
|
||||||
|
this.saveItems(dirtyItems, function(response){
|
||||||
|
modelManager.clearDirtyItems();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.saveItems = function(items, callback) {
|
||||||
|
var request = Restangular.one("users", user.uuid).one("items");
|
||||||
request.items = _.map(items, function(item){
|
request.items = _.map(items, function(item){
|
||||||
return this.createRequestParamsFromItem(item, user);
|
return this.createRequestParamsFromItem(item, user);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
request.put().then(function(response){
|
|
||||||
var success = response.plain().success;
|
request.post().then(function(response) {
|
||||||
callback(success);
|
var savedItems = response.items;
|
||||||
|
items.forEach(function(item){
|
||||||
|
_.merge(item, _.find(savedItems, {uuid: item.uuid}));
|
||||||
})
|
})
|
||||||
}
|
callback(response);
|
||||||
|
|
||||||
this.saveItem = function(user, item, callback) {
|
|
||||||
if(!user.id) {
|
|
||||||
this.writeUserToLocalStorage(user);
|
|
||||||
callback(item);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
angular
|
angular
|
||||||
.module('app.services')
|
.module('app.frontend')
|
||||||
.directive('mbAutofocus', ['$timeout', function($timeout) {
|
.directive('mbAutofocus', ['$timeout', function($timeout) {
|
||||||
return {
|
return {
|
||||||
restrict: 'A',
|
restrict: 'A',
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
angular
|
angular
|
||||||
.module('app.services')
|
.module('app.frontend')
|
||||||
.directive('draggable', function() {
|
.directive('draggable', function() {
|
||||||
return {
|
return {
|
||||||
scope: {
|
scope: {
|
||||||
@@ -35,7 +35,7 @@ angular
|
|||||||
});
|
});
|
||||||
|
|
||||||
angular
|
angular
|
||||||
.module('app.services')
|
.module('app.frontend')
|
||||||
.directive('droppable', function() {
|
.directive('droppable', function() {
|
||||||
return {
|
return {
|
||||||
scope: {
|
scope: {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
angular
|
angular
|
||||||
.module('app.services')
|
.module('app.frontend')
|
||||||
.directive('fileChange', function() {
|
.directive('fileChange', function() {
|
||||||
return {
|
return {
|
||||||
restrict: 'A',
|
restrict: 'A',
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
angular
|
angular
|
||||||
.module('app.services')
|
.module('app.frontend')
|
||||||
.directive('lowercase', function() {
|
.directive('lowercase', function() {
|
||||||
return {
|
return {
|
||||||
require: 'ngModel',
|
require: 'ngModel',
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
angular
|
angular
|
||||||
.module('app.services')
|
.module('app.frontend')
|
||||||
.directive('selectOnClick', ['$window', function ($window) {
|
.directive('selectOnClick', ['$window', function ($window) {
|
||||||
return {
|
return {
|
||||||
restrict: 'A',
|
restrict: 'A',
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
angular
|
angular
|
||||||
.module('app.services')
|
.module('app.frontend')
|
||||||
.directive('note', function($timeout) {
|
.directive('note', function($timeout) {
|
||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
|
|
||||||
angular
|
angular
|
||||||
.module('app.services').directive('typewrite', ['$timeout', function ($timeout) {
|
.module('app.frontend').directive('typewrite', ['$timeout', function ($timeout) {
|
||||||
function linkFunction($scope, $element, $attrs) {
|
function linkFunction($scope, $element, $attrs) {
|
||||||
var timer = null,
|
var timer = null,
|
||||||
initialDelay = $attrs.initialDelay ? getTypeDelay($attrs.initialDelay) : 200,
|
initialDelay = $attrs.initialDelay ? getTypeDelay($attrs.initialDelay) : 200,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
class ItemManager() {
|
class ItemManager {
|
||||||
|
|
||||||
set items(items) {
|
set items(items) {
|
||||||
this.items = items;
|
this.items = items;
|
||||||
@@ -27,8 +27,8 @@ class ItemManager() {
|
|||||||
// returns dirty item references that need saving
|
// returns dirty item references that need saving
|
||||||
deleteItem(item) {
|
deleteItem(item) {
|
||||||
_.remove(this.items, item);
|
_.remove(this.items, item);
|
||||||
item.references.forEach(function(reference){
|
item.references.forEach(function(referencedItem){
|
||||||
removeReferencesFromItem(reference, item);
|
removeReferencesBetweenItems(referencedItem, item);
|
||||||
})
|
})
|
||||||
|
|
||||||
return item.references;
|
return item.references;
|
||||||
@@ -40,16 +40,11 @@ class ItemManager() {
|
|||||||
return [itemOne, itemTwo];
|
return [itemOne, itemTwo];
|
||||||
}
|
}
|
||||||
|
|
||||||
removeReferencesBetweenItems(itemOne, itemTwo) {
|
|
||||||
itemOne.references.push(itemTwo);
|
|
||||||
itemTwo.references.push(itemOne);
|
|
||||||
return [itemOne, itemTwo];
|
|
||||||
}
|
|
||||||
|
|
||||||
createReferencesBetweenItems(itemOne, itemTwo) {
|
createReferencesBetweenItems(itemOne, itemTwo) {
|
||||||
itemOne.references.push(itemTwo);
|
itemOne.references.push(itemTwo);
|
||||||
itemTwo.references.push(itemOne);
|
itemTwo.references.push(itemOne);
|
||||||
return [itemOne, itemTwo];
|
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) {
|
.service('markdownRenderer', function ($sce) {
|
||||||
|
|
||||||
marked.setOptions({
|
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) {
|
.service('serverSideValidation', function ($sce) {
|
||||||
// Show validation errors in form.
|
// Show validation errors in form.
|
||||||
this.showErrors = function (formErrors, 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_tree ./app/services
|
||||||
|
|
||||||
//= require app/app.frontend.js
|
//= require app/app.frontend.js
|
||||||
|
|||||||
@@ -2,10 +2,14 @@
|
|||||||
"name": "neeto",
|
"name": "neeto",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"babel-cli": "^6.18.0",
|
||||||
|
"babel-preset-env": "^1.1.1",
|
||||||
"babel-preset-es2015": "^6.18.0",
|
"babel-preset-es2015": "^6.18.0",
|
||||||
|
"babel-preset-es2016": "^6.16.0",
|
||||||
"grunt": "^1.0.1",
|
"grunt": "^1.0.1",
|
||||||
"grunt-angular-templates": "^1.1.0",
|
"grunt-angular-templates": "^1.1.0",
|
||||||
"grunt-babel": "^6.0.0",
|
"grunt-babel": "^6.0.0",
|
||||||
|
"grunt-browserify": "^5.0.0",
|
||||||
"grunt-contrib-concat": "^1.0.1",
|
"grunt-contrib-concat": "^1.0.1",
|
||||||
"grunt-contrib-cssmin": "^1.0.2",
|
"grunt-contrib-cssmin": "^1.0.2",
|
||||||
"grunt-contrib-jshint": "~0.10.0",
|
"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