Add sgFolderTree directive

pull/91/head
Francis Lachapelle 2014-11-23 01:09:04 -05:00
parent 277bdd2b1c
commit 2cb5aecdcb
4 changed files with 176 additions and 33 deletions

View File

@ -45,6 +45,7 @@ module.exports = function(grunt) {
'<%= src %>/angular-animate/angular-animate{,.min}.js{,.map}',
'<%= src %>/angular-sanitize/angular-sanitize{,.min}.js{,.map}',
'<%= src %>/angular-ui-router/release/angular-ui-router{,.min}.js',
'<%= src %>/angular-recursion/angular-recursion{,.min}.js',
'<%= src %>/angular-foundation/mm-foundation-tpls{,.min}.js',
'<%= src %>/foundation/js/foundation{,.min}.js',
'<%= src %>/ionic/release/js/ionic.bundle{,.min}.js',

View File

@ -6,6 +6,7 @@
"angular-animate": "~1.2",
"angular-ui-router": "~0.2",
"angular-foundation": "~0.3",
"angular-recursion": "~1.0",
"foundation": ">5.3",
"ionic": "1.0.0-beta.11",
"underscore": "~1.6"

View File

@ -109,7 +109,7 @@
}];
/* Angular module instanciation */
angular.module('SOGo.UIDesktop', ['mm.foundation'])
angular.module('SOGo.UIDesktop', ['mm.foundation', 'RecursionHelper'])
/* Factory registration in Angular module */
.factory('sgDialog', Dialog.$factory)
@ -128,20 +128,118 @@
};
})
/*
* sgDropdownContentToggle - Provides dropdown content functionality
* @restrict class or attribute
* @see https://github.com/pineconellc/angular-foundation/blob/master/src/dropdownToggle/dropdownToggle.js
* @example:
/*
* sgFolderTree - Provides hierarchical folders tree
* @memberof SOGo.UIDesktop
* @restrict element
* @see https://github.com/marklagendijk/angular-recursion
* @example:
<a dropdown-toggle="#dropdown-content">My Dropdown Content</a>
<div id="dropdown-content" class="sg-dropdown-content">
<div>
<h1>Hello</h1>
<p>World!</p>
</div>
</div>
*/
<sg-folder-tree data-ng-repeat="folder in folders track by folder.id"
data-sg-root="account"
data-sg-folder="folder"
data-sg-set-folder="setCurrentFolder"><!-- tree --></sg-folder-tree>
*/
.directive('sgFolderTree', function(RecursionHelper) {
return {
restrict: 'E',
replace: true,
scope: {
root: '=sgRoot',
folder: '=sgFolder',
setFolder: '=sgSetFolder'
},
template:
'<div>' +
' <li>' +
' <span class="folder-container">' +
' <span class="folder-content">' +
' <i class="icon icon-ion-folder"></i>' +
' <form>' +
' <a data-ng-cloak="ng-cloak"' +
' >{{folder.name}}</a>' +
' </form>' +
' <span class="icon ng-hide" data-ng-cloak="ng-cloak">' +
' <a class="icon" href="#"' +
' data-dropdown-toggle="#folderProperties"' +
' data-options="align:right"><i class="icon-cog"></i></a>' +
' </span>' +
' </span>' +
' </span>' +
' </li>' +
' <div>' +
' <span ng-repeat="child in folder.children track by child.path">' +
' <sg-folder-tree data-sg-root="root" data-sg-folder="child" data-sg-set-folder="setFolder"></sg-folder-tree>' +
' </span>' +
' </div>' +
'</div>',
compile: function(element) {
return RecursionHelper.compile(element, function(scope, iElement, iAttrs, controller, transcludeFn) {
// Set CSS class for folder hierarchical level
var level = scope.folder.path.split('/').length - 1;
angular.element(iElement.find('i')[0]).addClass('childLevel' + level);
var link = iElement.find('a');
link.on('click', function() {
var list = iElement.parent();
while (list[0].tagName != 'UL') {
list = list.parent();
}
var items = list.find('li');
// Highlight element as "loading"
items.removeClass('_selected');
items.removeClass('_loading');
angular.element(iElement.find('li')[0]).addClass('_loading');
// Call external function
scope.setFolder(scope.root, scope.folder);
});
// TODO: rename folder on dbl-click
// link.on('dblclick', function() {
// });
scope.$on('sgSelectFolder', function(event, folderId) {
console.debug('select folder ' + folderId + ' = ' + scope.folder.id);
if (folderId == scope.folder.id) {
var list = iElement.parent();
while (list[0].tagName != 'UL') {
list = list.parent();
}
var items = list.find('li');
// Hightlight element as "selected"
angular.element(iElement.find('li')[0]).removeClass('_loading');
angular.element(iElement.find('li')[0]).addClass('_selected');
// Show options button
angular.forEach(items, function(element) {
var li = angular.element(element);
var spans = li.find('span');
angular.element(spans[2]).addClass('ng-hide');
});
angular.element(iElement.find('span')[2]).removeClass('ng-hide');
}
});
});
}
};
})
/*
* sgDropdownContentToggle - Provides dropdown content functionality
* @memberof SOGo.UIDesktop
* @restrict class or attribute
* @see https://github.com/pineconellc/angular-foundation/blob/master/src/dropdownToggle/dropdownToggle.js
* @example:
<a dropdown-toggle="#dropdown-content">My Dropdown Content</a>
<div id="dropdown-content" class="sg-dropdown-content">
<div>
<h1>Hello</h1>
<p>World!</p>
</div>
</div>
*/
.directive('sgDropdownContentToggle', ['$document', '$window', '$location', '$position', function ($document, $window, $location, $position) {
var openElement = null,
closeMenu = angular.noop;
@ -244,15 +342,15 @@
};
}])
/*
* sgSubscribe - Common subscription widget
* @restrict class or attribute
* @param {String} sgSubscribe - the folder type
* @param {Function} sgSubscribeOnSelect - the function to call when subscribing to a folder
* @example:
/*
* sgSubscribe - Common subscription widget
* @restrict class or attribute
* @param {String} sgSubscribe - the folder type
* @param {Function} sgSubscribeOnSelect - the function to call when subscribing to a folder
* @example:
<div sg-subscribe="contact" sg-subscribe-on-select="subscribeToFolder"></div>
*/
<div sg-subscribe="contact" sg-subscribe-on-select="subscribeToFolder"></div>
*/
.directive('sgSubscribe', [function() {
return {
restrict: 'CA',
@ -279,16 +377,16 @@
};
}])
/*
* sgUserTypeahead - Typeahead of users, used internally by sgSubscribe
* @restrict attribute
* @param {String} sgModel - the folder type
* @param {Function} sgSubscribeOnSelect - the function to call when subscribing to a folder
* @see https://github.com/pineconellc/angular-foundation/blob/master/src/typeahead/typeahead.js
* @example:
/*
* sgUserTypeahead - Typeahead of users, used internally by sgSubscribe
* @restrict attribute
* @param {String} sgModel - the folder type
* @param {Function} sgSubscribeOnSelect - the function to call when subscribing to a folder
* @see https://github.com/pineconellc/angular-foundation/blob/master/src/typeahead/typeahead.js
* @example:
<div sg-subscribe="contact" sg-subscribe-on-select="subscribeToFolder"></div>
*/
<div sg-subscribe="contact" sg-subscribe-on-select="subscribeToFolder"></div>
*/
.directive('sgUserTypeahead', ['$parse', '$q', '$timeout', '$position', 'sgUser', function($parse, $q, $timeout, $position, User) {
return {
restrict: 'A',

View File

@ -46,8 +46,51 @@
}];
/* Angular module instanciation */
angular.module('SOGo.UIMobile', ['ionic'])
angular.module('SOGo.UIMobile', ['ionic', 'RecursionHelper'])
/* Factory registration in Angular module */
.factory('sgDialog', Dialog.$factory);
.factory('sgDialog', Dialog.$factory)
/*
* sgFolderTree - Provides hierarchical folders tree
* @memberof SOGo.UIDesktop
* @restrict element
* @see https://github.com/marklagendijk/angular-recursion
* @example:
<sg-folder-tree data-ng-repeat="folder in folders track by folder.id"
data-sg-root="account"
data-sg-folder="folder"
data-sg-set-folder="setCurrentFolder"><!-- tree --></sg-folder-tree>
*/
.directive("sgFolderTree", function(RecursionHelper) {
return {
restrict: "E",
scope: {
root: '=sgRoot',
folder: '=sgFolder',
setFolder: '=sgSetFolder'
},
template:
'<ion-item option-buttons="buttons" class="item-icon-left item-icon-right"' +
' ng-click="setFolder(root, folder)">' +
' <i class="icon ion-folder"><!-- mailbox --></i>{{folder.name}}' +
' <i class="icon ion-ios7-arrow-right"><!-- right arrow icon --></i>' +
' <ion-option-button class="button-info"' +
' ng-click="edit(folder)">{{"Edit" | loc}}</ion-option-button>' +
'</ion-item>' +
'<div>' +
' <span ng-repeat="child in folder.children track by child.id">' +
' <sg-folder-tree sg-root="root" sg-folder="child" sg-set-folder="setFolder"></sg-folder-tree>' +
' </span>' +
'</div>',
compile: function(element) {
return RecursionHelper.compile(element, function(scope, iElement, iAttrs, controller, transcludeFn) {
var level = scope.folder.path.split('/').length - 1;
iElement.find('ion-item').addClass('childLevel' + level);
});
}
};
});
})();