diff --git a/guacamole/src/main/webapp/app/groupList/directives/guacGroupList.js b/guacamole/src/main/webapp/app/groupList/directives/guacGroupList.js index 0b5ed6f90..d5404c778 100644 --- a/guacamole/src/main/webapp/app/groupList/directives/guacGroupList.js +++ b/guacamole/src/main/webapp/app/groupList/directives/guacGroupList.js @@ -67,6 +67,17 @@ angular.module('groupList').directive('guacGroupList', [function guacGroupList() */ connectionGroupTemplate : '=', + /** + * The URL or ID of the Angular template to use when rendering a + * sharing profile. The @link{GroupListItem} associated with that + * sharing profile will be exposed within the scope of the template + * as item, and the arbitrary context object, if any, + * will be exposed as context. + * + * @type String + */ + sharingProfileTemplate : '=', + /** * Whether the root of the connection group hierarchy given should * be shown. If false (the default), only the descendants of the @@ -165,6 +176,22 @@ angular.module('groupList').directive('guacGroupList', [function guacGroupList() return item.isConnectionGroup && !!$scope.connectionGroupTemplate; }; + /** + * Returns whether the given item represents a sharing profile that + * can be displayed. If there is no sharing profile template, then + * no sharing profile is visible. + * + * @param {GroupListItem} item + * The item to check. + * + * @returns {Boolean} + * true if the given item is a sharing profile that can be + * displayed, false otherwise. + */ + $scope.isVisibleSharingProfile = function isVisibleSharingProfile(item) { + return item.isSharingProfile && !!$scope.sharingProfileTemplate; + }; + // Set contents whenever the connection group is assigned or changed $scope.$watch('connectionGroups', function setContents(connectionGroups) { @@ -185,7 +212,8 @@ angular.module('groupList').directive('guacGroupList', [function guacGroupList() // Create root item for current connection group var rootItem = GroupListItem.fromConnectionGroup(dataSource, connectionGroup, - !!$scope.connectionTemplate, countActiveConnections); + !!$scope.connectionTemplate, !!$scope.sharingProfileTemplate, + countActiveConnections); // If root group is to be shown, add it as a root item if ($scope.showRootGroup) diff --git a/guacamole/src/main/webapp/app/groupList/templates/guacGroupList.html b/guacamole/src/main/webapp/app/groupList/templates/guacGroupList.html index 19d9fd508..df9b5b6c1 100644 --- a/guacamole/src/main/webapp/app/groupList/templates/guacGroupList.html +++ b/guacamole/src/main/webapp/app/groupList/templates/guacGroupList.html @@ -1,38 +1,60 @@
-
-
+
diff --git a/guacamole/src/main/webapp/app/groupList/types/GroupListItem.js b/guacamole/src/main/webapp/app/groupList/types/GroupListItem.js index a46eb204b..2fc9cf5b0 100644 --- a/guacamole/src/main/webapp/app/groupList/types/GroupListItem.js +++ b/guacamole/src/main/webapp/app/groupList/types/GroupListItem.js @@ -37,16 +37,16 @@ angular.module('groupList').factory('GroupListItem', ['ConnectionGroup', functio template = template || {}; /** - * The identifier of the data source associated with the connection or - * connection group this item represents. + * The identifier of the data source associated with the connection, + * connection group, or sharing profile this item represents. * * @type String */ this.dataSource = template.dataSource; /** - * The unique identifier associated with the connection or connection - * group this item represents. + * The unique identifier associated with the connection, connection + * group, or sharing profile this item represents. * * @type String */ @@ -78,7 +78,7 @@ angular.module('groupList').factory('GroupListItem', ['ConnectionGroup', functio /** * Whether this item represents a connection. If this item represents - * a connection group, this MUST be false. + * a connection group or sharing profile, this MUST be false. * * @type Boolean */ @@ -86,12 +86,20 @@ angular.module('groupList').factory('GroupListItem', ['ConnectionGroup', functio /** * Whether this item represents a connection group. If this item - * represents a connection, this MUST be false. + * represents a connection or sharing profile, this MUST be false. * * @type Boolean */ this.isConnectionGroup = template.isConnectionGroup; + /** + * Whether this item represents a sharing profile. If this item + * represents a connection or connection group, this MUST be false. + * + * @type Boolean + */ + this.isSharingProfile = template.isSharingProfile; + /** * Whether this item represents a balancing connection group. * @@ -107,8 +115,8 @@ angular.module('groupList').factory('GroupListItem', ['ConnectionGroup', functio this.isExpanded = template.isExpanded; /** - * Returns the number of currently active users for this connection or - * connection group, if known. + * Returns the number of currently active users for this connection, + * connection group, or sharing profile, if known. * * @type Number */ @@ -117,10 +125,10 @@ angular.module('groupList').factory('GroupListItem', ['ConnectionGroup', functio }); /** - * The connection or connection group whose data is exposed within - * this GroupListItem. + * The connection, connection group, or sharing profile whose data is + * exposed within this GroupListItem. * - * @type Connection|ConnectionGroup + * @type Connection|ConnectionGroup|SharingProfile */ this.wrappedItem = template.wrappedItem; @@ -137,6 +145,10 @@ angular.module('groupList').factory('GroupListItem', ['ConnectionGroup', functio * The connection whose contents should be represented by the new * GroupListItem. * + * @param {Boolean} [includeSharingProfiles=true] + * Whether sharing profiles should be included in the contents of the + * resulting GroupListItem. By default, sharing profiles are included. + * * @param {Function} [countActiveConnections] * A getter which returns the current number of active connections for * the given connection. If omitted, the number of active connections @@ -148,7 +160,17 @@ angular.module('groupList').factory('GroupListItem', ['ConnectionGroup', functio * A new GroupListItem which represents the given connection. */ GroupListItem.fromConnection = function fromConnection(dataSource, - connection, countActiveConnections) { + connection, includeSharingProfiles, countActiveConnections) { + + var children = []; + + // Add any sharing profiles + if (connection.sharingProfiles && includeSharingProfiles !== false) { + connection.sharingProfiles.forEach(function addSharingProfile(child) { + children.push(GroupListItem.fromSharingProfile(dataSource, + child, countActiveConnections)); + }); + } // Return item representing the given connection return new GroupListItem({ @@ -162,7 +184,11 @@ angular.module('groupList').factory('GroupListItem', ['ConnectionGroup', functio // Type information isConnection : true, isConnectionGroup : false, - + isSharingProfile : false, + + // Already-converted children + children : children, + // Count of currently active connections using this connection getActiveConnections : function getActiveConnections() { @@ -197,6 +223,10 @@ angular.module('groupList').factory('GroupListItem', ['ConnectionGroup', functio * Whether connections should be included in the contents of the * resulting GroupListItem. By default, connections are included. * + * @param {Boolean} [includeSharingProfiles=true] + * Whether sharing profiles should be included in the contents of the + * resulting GroupListItem. By default, sharing profiles are included. + * * @param {Function} [countActiveConnections] * A getter which returns the current number of active connections for * the given connection. If omitted, the number of active connections @@ -216,8 +246,8 @@ angular.module('groupList').factory('GroupListItem', ['ConnectionGroup', functio * including all descendants. */ GroupListItem.fromConnectionGroup = function fromConnectionGroup(dataSource, - connectionGroup, includeConnections, countActiveConnections, - countActiveConnectionGroups) { + connectionGroup, includeConnections, includeSharingProfiles, + countActiveConnections, countActiveConnectionGroups) { var children = []; @@ -225,7 +255,7 @@ angular.module('groupList').factory('GroupListItem', ['ConnectionGroup', functio if (connectionGroup.childConnections && includeConnections !== false) { connectionGroup.childConnections.forEach(function addChildConnection(child) { children.push(GroupListItem.fromConnection(dataSource, child, - countActiveConnections)); + includeSharingProfiles, countActiveConnections)); }); } @@ -233,8 +263,8 @@ angular.module('groupList').factory('GroupListItem', ['ConnectionGroup', functio if (connectionGroup.childConnectionGroups) { connectionGroup.childConnectionGroups.forEach(function addChildGroup(child) { children.push(GroupListItem.fromConnectionGroup(dataSource, - child, includeConnections, countActiveConnections, - countActiveConnectionGroups)); + child, includeConnections, includeSharingProfiles, + countActiveConnections, countActiveConnectionGroups)); }); } @@ -249,6 +279,7 @@ angular.module('groupList').factory('GroupListItem', ['ConnectionGroup', functio // Type information isConnection : false, isConnectionGroup : true, + isSharingProfile : false, isBalancing : connectionGroup.type === ConnectionGroup.Type.BALANCING, // Already-converted children @@ -273,6 +304,44 @@ angular.module('groupList').factory('GroupListItem', ['ConnectionGroup', functio }; + /** + * Creates a new GroupListItem using the contents of the given sharing + * profile. + * + * @param {String} dataSource + * The identifier of the data source containing the given sharing + * profile. + * + * @param {SharingProfile} sharingProfile + * The sharing profile whose contents should be represented by the new + * GroupListItem. + * + * @returns {GroupListItem} + * A new GroupListItem which represents the given sharing profile. + */ + GroupListItem.fromSharingProfile = function fromSharingProfile(dataSource, + sharingProfile) { + + // Return item representing the given sharing profile + return new GroupListItem({ + + // Identifying information + name : sharingProfile.name, + identifier : sharingProfile.identifier, + dataSource : dataSource, + + // Type information + isConnection : false, + isConnectionGroup : false, + isSharingProfile : true, + + // Wrapped item + wrappedItem : sharingProfile + + }); + + }; + return GroupListItem; }]);