diff --git a/UI/WebServerResources/Gruntfile.js b/UI/WebServerResources/Gruntfile.js index a575838c4..3120350be 100644 --- a/UI/WebServerResources/Gruntfile.js +++ b/UI/WebServerResources/Gruntfile.js @@ -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', diff --git a/UI/WebServerResources/bower.json b/UI/WebServerResources/bower.json index 128175c2b..4ca677f8c 100644 --- a/UI/WebServerResources/bower.json +++ b/UI/WebServerResources/bower.json @@ -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" diff --git a/UI/WebServerResources/js/Common/ui-desktop.js b/UI/WebServerResources/js/Common/ui-desktop.js index 846477701..18ee36272 100644 --- a/UI/WebServerResources/js/Common/ui-desktop.js +++ b/UI/WebServerResources/js/Common/ui-desktop.js @@ -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: - My Dropdown Content - - */ + + */ + .directive('sgFolderTree', function(RecursionHelper) { + return { + restrict: 'E', + replace: true, + scope: { + root: '=sgRoot', + folder: '=sgFolder', + setFolder: '=sgSetFolder' + }, + template: + '
' + + '
  • ' + + ' ' + + ' ' + + ' ' + + '
    ' + + ' {{folder.name}}' + + '
    ' + + ' ' + + ' ' + + ' ' + + '
    ' + + '
    ' + + '
  • ' + + '
    ' + + ' ' + + ' ' + + ' ' + + '
    ' + + '
    ', + 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: + + My Dropdown Content + + */ .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: -
    - */ +
    + */ .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: -
    - */ +
    + */ .directive('sgUserTypeahead', ['$parse', '$q', '$timeout', '$position', 'sgUser', function($parse, $q, $timeout, $position, User) { return { restrict: 'A', diff --git a/UI/WebServerResources/js/Common/ui-mobile.js b/UI/WebServerResources/js/Common/ui-mobile.js index 561997a02..bece843b0 100644 --- a/UI/WebServerResources/js/Common/ui-mobile.js +++ b/UI/WebServerResources/js/Common/ui-mobile.js @@ -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: + + + */ + .directive("sgFolderTree", function(RecursionHelper) { + return { + restrict: "E", + scope: { + root: '=sgRoot', + folder: '=sgFolder', + setFolder: '=sgSetFolder' + }, + template: + '' + + ' {{folder.name}}' + + ' ' + + ' {{"Edit" | loc}}' + + '' + + '
    ' + + ' ' + + ' ' + + ' ' + + '
    ', + 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); + }); + } + }; + }); + })();