working functionality

This commit is contained in:
Mo Bitar
2016-12-15 17:37:26 -06:00
parent 6a2e3e9ec1
commit 1722eb299c
31 changed files with 944 additions and 760 deletions

View File

@@ -63,7 +63,7 @@ angular.module('app.frontend')
}
}
})
.controller('EditorCtrl', function ($sce, $timeout, apiController, markdownRenderer, $rootScope) {
.controller('EditorCtrl', function ($sce, $timeout, apiController, modelManager, markdownRenderer, $rootScope) {
this.demoNotes = [
{title: "Live print a file with tail", content: "tail -f log/production.log"},
@@ -74,14 +74,14 @@ angular.module('app.frontend')
{title: "NPM install without sudo", content: "sudo chown -R $(whoami) ~/.npm"},
{title: "Email validation regex", content: "^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$"},
{title: "Ruby generate 256 bit key", content: "Digest::SHA256.hexdigest(SecureRandom.random_bytes(32))"},
{title: "Mac add user to user group", content: "sudo dseditgroup -o edit -a USERNAME -t user GROUPNAME"},
{title: "Mac add user to user tag", content: "sudo dsedittag -o edit -a USERNAME -t user GROUPNAME"},
{title: "Kill Mac OS System Apache", content: "sudo launchctl unload -w /System/Library/LaunchDaemons/org.apache.httpd.plist"},
{title: "Docker run with mount binding and port", content: "docker run -v /home/vagrant/www/app:/var/www/app -p 8080:80 -d kpi/s3"},
{title: "MySQL grant privileges", content: "GRANT [type of permission] ON [database name].[table name] TO [username]@'%;"},
{title: "MySQL list users", content: "SELECT User FROM mysql.user;"},
];
this.showSampler = !this.user.id && this.user.filteredNotes().length == 0;
this.showSampler = !this.user.id && modelManager.filteredNotes.length == 0;
this.demoNoteNames = _.map(this.demoNotes, function(note){
return note.title;

View File

@@ -1,104 +0,0 @@
angular.module('app.frontend')
.directive("groupsSection", function(){
return {
restrict: 'E',
scope: {
addNew: "&",
selectionMade: "&",
willSelect: "&",
save: "&",
groups: "=",
allGroup: "=",
user: "=",
updateNoteGroup: "&"
},
templateUrl: 'frontend/groups.html',
replace: true,
controller: 'GroupsCtrl',
controllerAs: 'ctrl',
bindToController: true,
link:function(scope, elem, attrs, ctrl) {
scope.$watch('ctrl.groups', function(newGroups){
if(newGroups) {
ctrl.setGroups(newGroups);
}
});
}
}
})
.controller('GroupsCtrl', function () {
var initialLoad = true;
this.setGroups = function(groups) {
if(initialLoad) {
initialLoad = false;
this.selectGroup(this.allGroup);
} else {
if(groups && groups.length > 0) {
this.selectGroup(groups[0]);
}
}
}
this.selectGroup = function(group) {
this.willSelect()(group);
this.selectedGroup = group;
this.selectionMade()(group);
}
this.clickedAddNewGroup = function() {
if(this.editingGroup) {
return;
}
this.newGroup = new Group({notes : []});
if(!this.user.uuid) {
this.newGroup.uuid = Neeto.crypto.generateRandomKey()
}
this.selectedGroup = this.newGroup;
this.editingGroup = this.newGroup;
this.addNew()(this.newGroup);
}
var originalGroupName = "";
this.onGroupTitleFocus = function(group) {
originalGroupName = group.name;
}
this.groupTitleDidChange = function(group) {
this.editingGroup = group;
}
this.saveGroup = function($event, group) {
this.editingGroup = null;
if(group.name.length == 0) {
group.name = originalGroupName;
originalGroupName = "";
return;
}
$event.target.blur();
if(!group.name || group.name.length == 0) {
return;
}
this.save()(group, function(savedGroup){
_.merge(group, savedGroup);
this.selectGroup(group);
this.newGroup = null;
}.bind(this));
}
this.noteCount = function(group) {
var validNotes = Note.filterDummyNotes(group.notes);
return validNotes.length;
}
this.handleDrop = function(e, newGroup, note) {
this.updateNoteGroup()(note, newGroup, this.selectedGroup);
}.bind(this)
});

View File

@@ -17,7 +17,7 @@ angular.module('app.frontend')
}
}
})
.controller('HeaderCtrl', function ($auth, $state, apiController, serverSideValidation, $timeout) {
.controller('HeaderCtrl', function ($auth, $state, apiController, modelManager, serverSideValidation, $timeout) {
this.changePasswordPressed = function() {
this.showNewPasswordForm = !this.showNewPasswordForm;
@@ -58,12 +58,12 @@ angular.module('app.frontend')
}
this.hasLocalData = function() {
return this.user.filteredNotes().length > 0;
return modelManager.filteredNotes.length > 0;
}
this.mergeLocalChanged = function() {
if(!this.user.shouldMerge) {
if(!confirm("Unchecking this option means any locally stored groups and notes you have now will be deleted. Are you sure you want to continue?")) {
if(!confirm("Unchecking this option means any locally stored tags and notes you have now will be deleted. Are you sure you want to continue?")) {
this.user.shouldMerge = true;
}
}
@@ -109,7 +109,7 @@ angular.module('app.frontend')
}
this.encryptionStatusForNotes = function() {
var allNotes = this.user.filteredNotes();
var allNotes = modelManager.filteredNotes;
var countEncrypted = 0;
allNotes.forEach(function(note){
if(note.encryptionEnabled()) {

View File

@@ -5,19 +5,19 @@ angular.module('app.frontend')
$rootScope.description = "A secure code box for developers to store common commands and useful notes.";
var onUserSet = function() {
apiController.setUser($scope.defaultUser);
$scope.allTag = new Tag({all: true});
$scope.allTag.content.name = "All";
$scope.tags = modelManager.tags;
$scope.allGroup = new Group({name: "All", all: true});
$scope.groups = modelManager.groups;
apiController.verifyEncryptionStatusOfAllItems($scope.defaultUser, function(success){
});
// apiController.verifyEncryptionStatusOfAllItems($scope.defaultUser, function(success){});
}
apiController.getCurrentUser(function(response){
if(response && !response.errors) {
console.log("Get user response", response);
$scope.defaultUser = new User(response);
modelManager.items = response.items;
modelManager.items = _.map(response.items, function(json_obj){return new Item(json_obj)});
$rootScope.title = "Notes — Neeto";
onUserSet();
} else {
@@ -27,44 +27,44 @@ angular.module('app.frontend')
});
/*
Groups Ctrl Callbacks
Tags Ctrl Callbacks
*/
$scope.updateAllGroup = function() {
$scope.allGroup.notes = modelManager.filteredNotes;
$scope.updateAllTag = function() {
$scope.allTag.notes = modelManager.filteredNotes;
}
$scope.groupsWillMakeSelection = function(group) {
if(group.all) {
$scope.updateAllGroup();
$scope.tagsWillMakeSelection = function(tag) {
if(tag.all) {
$scope.updateAllTag();
}
}
$scope.groupsSelectionMade = function(group) {
if(!group.notes) {
group.notes = [];
$scope.tagsSelectionMade = function(tag) {
if(!tag.notes) {
tag.notes = [];
}
$scope.selectedGroup = group;
$scope.selectedTag = tag;
}
$scope.groupsAddNew = function(group) {
modelManager.addTag(group);
$scope.tagsAddNew = function(tag) {
modelManager.addTag(tag);
}
$scope.groupsSave = function(group, callback) {
apiController.saveItems([group], callback);
$scope.tagsSave = function(tag, callback) {
apiController.saveItems([tag], callback);
}
/*
Called to update the group of a note after drag and drop change
Called to update the tag of a note after drag and drop change
The note object is a copy of the original
*/
$scope.groupsUpdateNoteGroup = function(noteCopy, newGroup, oldGroup) {
$scope.tagsUpdateNoteTag = function(noteCopy, newTag, oldTag) {
var originalNote = _.find($scope.defaultUser.notes, {uuid: noteCopy.uuid});
modelManager.removeTagFromNote(oldGroup, originalNote);
if(!newGroup.all) {
modelManager.addTagToNote(newGroup, originalNote);
modelManager.removeTagFromNote(oldTag, originalNote);
if(!newTag.all) {
modelManager.addTagToNote(newTag, originalNote);
}
apiController.saveDirtyItems(function(){});
@@ -74,19 +74,19 @@ angular.module('app.frontend')
Notes Ctrl Callbacks
*/
$scope.notesRemoveGroup = function(group) {
var validNotes = Note.filterDummyNotes(group.notes);
$scope.notesRemoveTag = function(tag) {
var validNotes = Note.filterDummyNotes(tag.notes);
if(validNotes == 0) {
// if no more notes, delete group
apiController.deleteItem($scope.defaultUser, group, function(){
// force scope groups to update on sub directives
$scope.groups = [];
// if no more notes, delete tag
apiController.deleteItem($scope.defaultUser, tag, function(){
// force scope tags to update on sub directives
$scope.tags = [];
$timeout(function(){
$scope.groups = modelManager.groups;
$scope.tags = modelManager.tags;
})
});
} else {
alert("To delete this group, remove all its notes first.");
alert("To delete this tag, remove all its notes first.");
}
}
@@ -95,15 +95,13 @@ angular.module('app.frontend')
}
$scope.notesAddNew = function(note) {
if(!$scope.defaultUser.id) {
// generate local id for note
note.id = Neeto.crypto.generateRandomKey();
}
modelManager.addNote(note);
if(!$scope.selectedGroup.all) {
modelManager.addTagToNote($scope.selectedGroup, note);
if(!$scope.selectedTag.all) {
console.log("add tag");
modelManager.addTagToNote($scope.selectedTag, note);
} else {
$scope.selectedTag.notes.unshift(note);
}
}
@@ -112,7 +110,9 @@ angular.module('app.frontend')
*/
$scope.saveNote = function(note, callback) {
apiController.saveItems([note], function(){
modelManager.addDirtyItems(note);
apiController.saveDirtyItems(function(){
modelManager.addNote(note);
note.hasChanges = false;
@@ -144,7 +144,7 @@ angular.module('app.frontend')
$scope.headerLogout = function() {
$scope.defaultUser = apiController.localUser();
$scope.groups = $scope.defaultUser.groups;
$scope.tags = $scope.defaultUser.tags;
}

View File

@@ -5,10 +5,11 @@ angular.module('app.frontend')
addNew: "&",
selectionMade: "&",
remove: "&",
group: "=",
tag: "=",
user: "=",
removeGroup: "&"
removeTag: "&"
},
templateUrl: 'frontend/notes.html',
replace: true,
controller: 'NotesCtrl',
@@ -16,15 +17,15 @@ angular.module('app.frontend')
bindToController: true,
link:function(scope, elem, attrs, ctrl) {
scope.$watch('ctrl.group', function(group, oldGroup){
if(group) {
ctrl.groupDidChange(group, oldGroup);
scope.$watch('ctrl.tag', function(tag, oldTag){
if(tag) {
ctrl.tagDidChange(tag, oldTag);
}
});
}
}
})
.controller('NotesCtrl', function (apiController, $timeout, ngDialog, $rootScope) {
.controller('NotesCtrl', function (apiController, modelManager, $timeout, ngDialog, $rootScope) {
$rootScope.$on("editorFocused", function(){
this.showMenu = false;
@@ -32,15 +33,15 @@ angular.module('app.frontend')
var isFirstLoad = true;
this.groupDidChange = function(group, oldGroup) {
this.tagDidChange = function(tag, oldTag) {
this.showMenu = false;
if(this.selectedNote && this.selectedNote.dummy) {
_.remove(oldGroup.notes, this.selectedNote);
_.remove(oldTag.notes, this.selectedNote);
}
this.noteFilter.text = "";
this.setNotes(group.notes, false);
this.setNotes(tag.notes, false);
if(isFirstLoad) {
$timeout(function(){
@@ -53,31 +54,31 @@ angular.module('app.frontend')
isFirstLoad = false;
}
}.bind(this))
} else if(group.notes.length == 0) {
} else if(tag.notes.length == 0) {
this.createNewNote();
}
}
this.selectedGroupDelete = function() {
this.selectedTagDelete = function() {
this.showMenu = false;
this.removeGroup()(this.group);
this.removeTag()(this.tag);
}
this.selectedGroupShare = function() {
this.selectedTagShare = function() {
this.showMenu = false;
if(!this.user.id) {
alert("You must be signed in to share a group.");
alert("You must be signed in to share a tag.");
return;
}
if(this.group.all) {
alert("You cannot share the 'All' group.");
if(this.tag.all) {
alert("You cannot share the 'All' tag.");
return;
}
var callback = function(username) {
apiController.shareItem(this.user, this.group, function(response){
apiController.shareItem(this.user, this.tag, function(response){
})
}.bind(this);
@@ -97,23 +98,23 @@ angular.module('app.frontend')
}
}
this.selectedGroupUnshare = function() {
this.selectedTagUnshare = function() {
this.showMenu = false;
apiController.unshareItem(this.user, this.group, function(response){
apiController.unshareItem(this.user, this.tag, function(response){
})
}
this.publicUrlForGroup = function() {
return this.group.presentation.url;
this.publicUrlForTag = function() {
return this.tag.presentation.url;
}
this.setNotes = function(notes, createNew) {
this.notes = notes;
console.log("set notes", notes);
notes.forEach(function(note){
note.visible = true;
})
apiController.decryptNotesWithLocalKey(notes);
this.selectFirstNote(createNew);
}
@@ -138,7 +139,9 @@ 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;
modelManager.addTagToNote(this.group, this.newNote);
if(this.tag && !this.tag.all) {
modelManager.addTagToNote(this.tag, this.newNote);
}
this.selectNote(this.newNote);
this.addNew()(this.newNote);
}

View File

@@ -0,0 +1,114 @@
angular.module('app.frontend')
.directive("tagsSection", function(){
return {
restrict: 'E',
scope: {
addNew: "&",
selectionMade: "&",
willSelect: "&",
save: "&",
tags: "=",
allTag: "=",
user: "=",
updateNoteTag: "&"
},
templateUrl: 'frontend/tags.html',
replace: true,
controller: 'TagsCtrl',
controllerAs: 'ctrl',
bindToController: true,
link:function(scope, elem, attrs, ctrl) {
scope.$watch('ctrl.tags', function(newTags){
if(newTags) {
ctrl.setTags(newTags);
}
});
scope.$watch('ctrl.allTag', function(allTag){
if(allTag) {
ctrl.setAllTag(allTag);
}
});
}
}
})
.controller('TagsCtrl', function () {
var initialLoad = true;
this.setAllTag = function(allTag) {
this.selectTag(this.allTag);
}
this.setTags = function(tags) {
if(initialLoad) {
initialLoad = false;
this.selectTag(this.allTag);
} else {
if(tags && tags.length > 0) {
this.selectTag(tags[0]);
}
}
}
this.selectTag = function(tag) {
this.willSelect()(tag);
this.selectedTag = tag;
this.selectionMade()(tag);
}
this.clickedAddNewTag = function() {
if(this.editingTag) {
return;
}
this.newTag = new Tag({notes : []});
if(!this.user.uuid) {
this.newTag.uuid = Neeto.crypto.generateRandomKey()
}
this.selectedTag = this.newTag;
this.editingTag = this.newTag;
this.addNew()(this.newTag);
}
var originalTagName = "";
this.onTagTitleFocus = function(tag) {
originalTagName = tag.content.name;
}
this.tagTitleDidChange = function(tag) {
this.editingTag = tag;
}
this.saveTag = function($event, tag) {
this.editingTag = null;
if(tag.content.name.length == 0) {
tag.content.name = originalTagName;
originalTagName = "";
return;
}
$event.target.blur();
if(!tag.content.name || tag.content.name.length == 0) {
return;
}
this.save()(tag, function(savedTag){
_.merge(tag, savedTag);
this.selectTag(tag);
this.newTag = null;
}.bind(this));
}
this.noteCount = function(tag) {
var validNotes = Note.filterDummyNotes(tag.notes);
return validNotes.length;
}
this.handleDrop = function(e, newTag, note) {
this.updateNoteTag()(note, newTag, this.selectedTag);
}.bind(this)
});