mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-10-31 00:53:21 +00:00 
			
		
		
		
	Merge pull request #24 from glyptodon/cleanup-angular
GUAC-932: Partially restore admin UI
This commit is contained in:
		| @@ -35,7 +35,47 @@ angular.module('groupList').directive('guacGroupList', [function guacGroupList() | |||||||
|              * |              * | ||||||
|              * @type ConnectionGroup|Object  |              * @type ConnectionGroup|Object  | ||||||
|              */ |              */ | ||||||
|             connectionGroup : '=' |             connectionGroup : '=', | ||||||
|  |  | ||||||
|  |             /** | ||||||
|  |              * Arbitrary object which shall be made available to the connection | ||||||
|  |              * and connection group templates within the scope as | ||||||
|  |              * <code>context</code>. | ||||||
|  |              *  | ||||||
|  |              * @type Object | ||||||
|  |              */ | ||||||
|  |             context : '=', | ||||||
|  |  | ||||||
|  |             /** | ||||||
|  |              * The URL or ID of the Angular template to use when rendering a | ||||||
|  |              * connection. The @link{GroupListItem} associated with that | ||||||
|  |              * connection will be exposed within the scope of the template | ||||||
|  |              * as <code>item</code>, and the arbitrary context object, if any, | ||||||
|  |              * will be exposed as <code>context</code>. | ||||||
|  |              * | ||||||
|  |              * @type String | ||||||
|  |              */ | ||||||
|  |             connectionTemplate : '=', | ||||||
|  |  | ||||||
|  |             /** | ||||||
|  |              * The URL or ID of the Angular template to use when rendering a | ||||||
|  |              * connection group. The @link{GroupListItem} associated with that | ||||||
|  |              * connection group will be exposed within the scope of the | ||||||
|  |              * template as <code>item</code>, and the arbitrary context object, | ||||||
|  |              * if any, will be exposed as <code>context</code>. | ||||||
|  |              * | ||||||
|  |              * @type String | ||||||
|  |              */ | ||||||
|  |             connectionGroupTemplate : '=', | ||||||
|  |  | ||||||
|  |             /** | ||||||
|  |              * Whether the root of the connection group hierarchy given should | ||||||
|  |              * be shown. If false (the default), only the descendants of the | ||||||
|  |              * given connection group will be listed. | ||||||
|  |              *  | ||||||
|  |              * @type Boolean | ||||||
|  |              */ | ||||||
|  |             showRootGroup : '=' | ||||||
|  |  | ||||||
|         }, |         }, | ||||||
|  |  | ||||||
| @@ -48,8 +88,24 @@ angular.module('groupList').directive('guacGroupList', [function guacGroupList() | |||||||
|             // Set contents whenever the connection group is assigned or changed |             // Set contents whenever the connection group is assigned or changed | ||||||
|             $scope.$watch("connectionGroup", function setContents(connectionGroup) { |             $scope.$watch("connectionGroup", function setContents(connectionGroup) { | ||||||
|  |  | ||||||
|                 if (connectionGroup) |                 if (connectionGroup) { | ||||||
|                     $scope.rootItem = GroupListItem.fromConnectionGroup(connectionGroup); |  | ||||||
|  |                     // Create item hierarchy | ||||||
|  |                     var rootItem = GroupListItem.fromConnectionGroup(connectionGroup); | ||||||
|  |  | ||||||
|  |                     // If root group is to be shown, wrap that group as the child of a fake root group | ||||||
|  |                     if ($scope.showRootGroup) | ||||||
|  |                         $scope.rootItem = new GroupListItem({ | ||||||
|  |                             isConnectionGroup : true, | ||||||
|  |                             isBalancing       : false, | ||||||
|  |                             children          : [ rootItem ] | ||||||
|  |                         }); | ||||||
|  |  | ||||||
|  |                     // If not wrapped, only the descendants of the root will be shown | ||||||
|  |                     else | ||||||
|  |                         $scope.rootItem = rootItem; | ||||||
|  |  | ||||||
|  |                 } | ||||||
|                 else |                 else | ||||||
|                     $scope.rootItem = null; |                     $scope.rootItem = null; | ||||||
|  |  | ||||||
| @@ -63,7 +119,7 @@ angular.module('groupList').directive('guacGroupList', [function guacGroupList() | |||||||
|              *     connection group. |              *     connection group. | ||||||
|              */ |              */ | ||||||
|             $scope.toggleExpanded = function toggleExpanded(groupListItem) { |             $scope.toggleExpanded = function toggleExpanded(groupListItem) { | ||||||
|                 groupListItem.expanded = !groupListItem.expanded; |                 groupListItem.isExpanded = !groupListItem.isExpanded; | ||||||
|             }; |             }; | ||||||
|              |              | ||||||
|         }] |         }] | ||||||
|   | |||||||
| @@ -1,21 +0,0 @@ | |||||||
| /* |  | ||||||
|  * Copyright (C) 2014 Glyptodon LLC |  | ||||||
|  * |  | ||||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy |  | ||||||
|  * of this software and associated documentation files (the "Software"), to deal |  | ||||||
|  * in the Software without restriction, including without limitation the rights |  | ||||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |  | ||||||
|  * copies of the Software, and to permit persons to whom the Software is |  | ||||||
|  * furnished to do so, subject to the following conditions: |  | ||||||
|  * |  | ||||||
|  * The above copyright notice and this permission notice shall be included in |  | ||||||
|  * all copies or substantial portions of the Software. |  | ||||||
|  * |  | ||||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |  | ||||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |  | ||||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |  | ||||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |  | ||||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |  | ||||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |  | ||||||
|  * THE SOFTWARE. |  | ||||||
|  */ |  | ||||||
| @@ -25,35 +25,18 @@ | |||||||
|  |  | ||||||
|         <!-- Connection --> |         <!-- Connection --> | ||||||
|         <div class="connection" ng-show="item.isConnection"> |         <div class="connection" ng-show="item.isConnection"> | ||||||
|             <a ng-href="#/client/c/{{item.identifier}}"> |             <ng-include src="connectionTemplate"/> | ||||||
|                 <div class="caption"> |  | ||||||
|  |  | ||||||
|                     <!-- Connection icon --> |  | ||||||
|                     <div class="protocol"> |  | ||||||
|                         <div class="icon type" ng-class="item.protocol"></div> |  | ||||||
|                     </div> |  | ||||||
|  |  | ||||||
|                     <!-- Connection name --> |  | ||||||
|                     <span class="name">{{item.name}}</span> |  | ||||||
|  |  | ||||||
|                 </div> |  | ||||||
|             </a> |  | ||||||
|         </div> |         </div> | ||||||
|  |  | ||||||
|         <!-- Connection group --> |         <!-- Connection group --> | ||||||
|         <div class="group" ng-show="item.isConnectionGroup"> |         <div class="group" ng-show="item.isConnectionGroup"> | ||||||
|  |  | ||||||
|             <div class="caption"> |             <div class="caption"> | ||||||
|  |  | ||||||
|                 <!-- Connection group icon --> |                 <!-- Connection group icon --> | ||||||
|                 <div class="icon group type" ng-click="toggleExpanded(item)" |                 <div class="icon group type" ng-click="toggleExpanded(item)" | ||||||
|                      ng-class="{expanded: item.isExpanded, empty: !item.children.length, balancer: item.isBalancing}"></div> |                      ng-class="{expanded: item.isExpanded, empty: !item.children.length, balancer: item.isBalancing}"></div> | ||||||
|  |  | ||||||
|                 <!-- Connection group name --> |                 <ng-include src="connectionGroupTemplate"/> | ||||||
|                 <span class="name"> |  | ||||||
|                     <a ng-show="item.isBalancing" ng-href="#/client/g/{{item.identifier}}">{{item.name}}</a> |  | ||||||
|                     <span ng-show="!item.isBalancing">{{item.name}}</span> |  | ||||||
|                 </span> |  | ||||||
|  |  | ||||||
|             </div> |             </div> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -101,6 +101,14 @@ angular.module('groupList').factory('GroupListItem', ['ConnectionGroup', functio | |||||||
|          */ |          */ | ||||||
|         this.isExpanded = template.isExpanded; |         this.isExpanded = template.isExpanded; | ||||||
|  |  | ||||||
|  |         /** | ||||||
|  |          * The connection or connection group whose data is exposed within | ||||||
|  |          * this GroupListItem. | ||||||
|  |          * | ||||||
|  |          * @type Connection|ConnectionGroup | ||||||
|  |          */ | ||||||
|  |         this.wrappedItem = template.wrappedItem; | ||||||
|  |  | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -125,7 +133,10 @@ angular.module('groupList').factory('GroupListItem', ['ConnectionGroup', functio | |||||||
|  |  | ||||||
|             // Type information |             // Type information | ||||||
|             isConnection      : true, |             isConnection      : true, | ||||||
|             isConnectionGroup : false |             isConnectionGroup : false, | ||||||
|  |  | ||||||
|  |             // Wrapped item | ||||||
|  |             wrappedItem : connection | ||||||
|  |  | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
| @@ -170,7 +181,10 @@ angular.module('groupList').factory('GroupListItem', ['ConnectionGroup', functio | |||||||
|             isBalancing       : connectionGroup.type === ConnectionGroup.Type.BALANCING, |             isBalancing       : connectionGroup.type === ConnectionGroup.Type.BALANCING, | ||||||
|  |  | ||||||
|             // Already-converted children |             // Already-converted children | ||||||
|             children : children |             children : children, | ||||||
|  |  | ||||||
|  |             // Wrapped item | ||||||
|  |             wrappedItem : connectionGroup | ||||||
|  |  | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										35
									
								
								guacamole/src/main/webapp/app/home/templates/connection.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								guacamole/src/main/webapp/app/home/templates/connection.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | <a ng-href="#/client/c/{{item.identifier}}"> | ||||||
|  |     <!-- | ||||||
|  |        Copyright (C) 2014 Glyptodon LLC | ||||||
|  |  | ||||||
|  |        Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  |        of this software and associated documentation files (the "Software"), to deal | ||||||
|  |        in the Software without restriction, including without limitation the rights | ||||||
|  |        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  |        copies of the Software, and to permit persons to whom the Software is | ||||||
|  |        furnished to do so, subject to the following conditions: | ||||||
|  |  | ||||||
|  |        The above copyright notice and this permission notice shall be included in | ||||||
|  |        all copies or substantial portions of the Software. | ||||||
|  |  | ||||||
|  |        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||||
|  |        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||||
|  |        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||||
|  |        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||||
|  |        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||||
|  |        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||||
|  |        THE SOFTWARE. | ||||||
|  |     --> | ||||||
|  |  | ||||||
|  |     <div class="caption"> | ||||||
|  |  | ||||||
|  |         <!-- Connection icon --> | ||||||
|  |         <div class="protocol"> | ||||||
|  |             <div class="icon type" ng-class="item.protocol"></div> | ||||||
|  |         </div> | ||||||
|  |  | ||||||
|  |         <!-- Connection name --> | ||||||
|  |         <span class="name">{{item.name}}</span> | ||||||
|  |  | ||||||
|  |     </div> | ||||||
|  | </a> | ||||||
| @@ -0,0 +1,26 @@ | |||||||
|  | <span class="name"> | ||||||
|  |     <!-- | ||||||
|  |        Copyright (C) 2014 Glyptodon LLC | ||||||
|  |  | ||||||
|  |        Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  |        of this software and associated documentation files (the "Software"), to deal | ||||||
|  |        in the Software without restriction, including without limitation the rights | ||||||
|  |        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  |        copies of the Software, and to permit persons to whom the Software is | ||||||
|  |        furnished to do so, subject to the following conditions: | ||||||
|  |  | ||||||
|  |        The above copyright notice and this permission notice shall be included in | ||||||
|  |        all copies or substantial portions of the Software. | ||||||
|  |  | ||||||
|  |        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||||
|  |        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||||
|  |        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||||
|  |        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||||
|  |        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||||
|  |        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||||
|  |        THE SOFTWARE. | ||||||
|  |     --> | ||||||
|  |  | ||||||
|  |     <a ng-show="item.isBalancing" ng-href="#/client/g/{{item.identifier}}">{{item.name}}</a> | ||||||
|  |     <span ng-show="!item.isBalancing">{{item.name}}</span> | ||||||
|  | </span> | ||||||
| @@ -36,7 +36,10 @@ | |||||||
|     <!-- All connections for this user --> |     <!-- All connections for this user --> | ||||||
|     <h2>{{'home.allConnections' | translate}}</h2> |     <h2>{{'home.allConnections' | translate}}</h2> | ||||||
|     <div class="all-connections" ng-class="{loading: loading}"> |     <div class="all-connections" ng-class="{loading: loading}"> | ||||||
|         <guac-group-list connection-group="rootConnectionGroup"/> |         <guac-group-list | ||||||
|  |             connection-group="rootConnectionGroup" | ||||||
|  |             connection-template="'app/home/templates/connection.html'" | ||||||
|  |             connection-group-template="'app/home/templates/connectionGroup.html'"/> | ||||||
|     </div> |     </div> | ||||||
|  |  | ||||||
| </div> | </div> | ||||||
| @@ -28,7 +28,6 @@ angular.module('manage').controller('connectionEditModalController', ['$scope', | |||||||
|              |              | ||||||
|     var connectionEditModal             = $injector.get('connectionEditModal'); |     var connectionEditModal             = $injector.get('connectionEditModal'); | ||||||
|     var connectionService               = $injector.get('connectionService'); |     var connectionService               = $injector.get('connectionService'); | ||||||
|     var displayObjectPreparationService = $injector.get('displayObjectPreparationService'); |  | ||||||
|     var Connection                      = $injector.get('Connection'); |     var Connection                      = $injector.get('Connection'); | ||||||
|     var HistoryEntryWrapper             = $injector.get('HistoryEntryWrapper'); |     var HistoryEntryWrapper             = $injector.get('HistoryEntryWrapper'); | ||||||
|      |      | ||||||
| @@ -39,9 +38,6 @@ angular.module('manage').controller('connectionEditModalController', ['$scope', | |||||||
|     $scope.connection = new Connection($scope.connection); |     $scope.connection = new Connection($scope.connection); | ||||||
|      |      | ||||||
|     var newConnection = !$scope.connection.identifier; |     var newConnection = !$scope.connection.identifier; | ||||||
|     if(newConnection) |  | ||||||
|         // Prepare this connection for display |  | ||||||
|         displayObjectPreparationService.prepareConnection($scope.connection); |  | ||||||
|      |      | ||||||
|     // Set it to VNC by default |     // Set it to VNC by default | ||||||
|     if(!$scope.connection.protocol) |     if(!$scope.connection.protocol) | ||||||
| @@ -50,9 +46,13 @@ angular.module('manage').controller('connectionEditModalController', ['$scope', | |||||||
|     $scope.historyEntryWrappers = []; |     $scope.historyEntryWrappers = []; | ||||||
|      |      | ||||||
|     // Wrap all the history entries |     // Wrap all the history entries | ||||||
|     $scope.connection.history.forEach(function wrapHistoryEntry(historyEntry) { |     if (!newConnection) { | ||||||
|        $scope.historyEntryWrappers.push(new HistoryEntryWrapper(historyEntry));  |         connectionService.getConnectionHistory($scope.connection.identifier).success(function wrapHistoryEntries(historyEntries) { | ||||||
|     }); |             historyEntries.forEach(function wrapHistoryEntry(historyEntry) { | ||||||
|  |                $scope.historyEntryWrappers.push(new HistoryEntryWrapper(historyEntry));  | ||||||
|  |             }); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|      |      | ||||||
|     /** |     /** | ||||||
|      * Close the modal. |      * Close the modal. | ||||||
|   | |||||||
| @@ -28,7 +28,6 @@ angular.module('manage').controller('connectionGroupEditModalController', ['$sco | |||||||
|              |              | ||||||
|     var connectionGroupEditModal        = $injector.get('connectionGroupEditModal'); |     var connectionGroupEditModal        = $injector.get('connectionGroupEditModal'); | ||||||
|     var connectionGroupService          = $injector.get('connectionGroupService'); |     var connectionGroupService          = $injector.get('connectionGroupService'); | ||||||
|     var displayObjectPreparationService = $injector.get('displayObjectPreparationService'); |  | ||||||
|      |      | ||||||
|     // Make a copy of the old connection group so that we can copy over the changes when done |     // Make a copy of the old connection group so that we can copy over the changes when done | ||||||
|     var oldConnectionGroup = $scope.connectionGroup; |     var oldConnectionGroup = $scope.connectionGroup; | ||||||
| @@ -66,9 +65,6 @@ angular.module('manage').controller('connectionGroupEditModalController', ['$sco | |||||||
|     $scope.save = function save() { |     $scope.save = function save() { | ||||||
|         connectionGroupService.saveConnectionGroup($scope.connectionGroup).success(function successfullyUpdatedConnectionGroup() { |         connectionGroupService.saveConnectionGroup($scope.connectionGroup).success(function successfullyUpdatedConnectionGroup() { | ||||||
|              |              | ||||||
|             // Prepare this connection group for display |  | ||||||
|             displayObjectPreparationService.prepareConnectionGroup($scope.connectionGroup); |  | ||||||
|              |  | ||||||
|             var oldParentID = oldConnectionGroup.parentIdentifier; |             var oldParentID = oldConnectionGroup.parentIdentifier; | ||||||
|             var newParentID = $scope.connectionGroup.parentIdentifier; |             var newParentID = $scope.connectionGroup.parentIdentifier; | ||||||
|              |              | ||||||
|   | |||||||
| @@ -60,120 +60,64 @@ angular.module('manage').controller('manageController', ['$scope', '$injector', | |||||||
|  |  | ||||||
|     }); |     }); | ||||||
|      |      | ||||||
|     /** |  | ||||||
|      * Move the connection or connection group within the group heirarchy,  |  | ||||||
|      * initially place a new item, or remove an item from the heirarchy. |  | ||||||
|      * @param {object} item The connection or connection group to move. |  | ||||||
|      * @param {string} fromID The ID of the group to move the item from, if relevant. |  | ||||||
|      * @param {string} toID The ID of the group to move the item to, if relevant. |  | ||||||
|      */ |  | ||||||
|     $scope.moveItem = function moveItem(item, fromID, toID) { |  | ||||||
|          |  | ||||||
|         // Remove the item from the old group, if there was one |  | ||||||
|         if(fromID) { |  | ||||||
|             var oldParent   = findGroup($scope.rootGroup, fromID), |  | ||||||
|                 oldChildren = oldParent.children; |  | ||||||
|              |  | ||||||
|             // Find and remove the item from the old group |  | ||||||
|             for(var i = 0; i < oldChildren.length; i++) { |  | ||||||
|                 var child = oldChildren[i]; |  | ||||||
|                 if(child.isConnection === item.isConnection && |  | ||||||
|                         child.identifier === item.identifier) { |  | ||||||
|                     oldChildren.splice(i, 1); |  | ||||||
|                     break; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|          |  | ||||||
|         // Add the item to the new group, if there is one |  | ||||||
|         if(toID) { |  | ||||||
|             var newParent = findGroup($scope.rootGroup, toID); |  | ||||||
|             newParent.children.push(item); |  | ||||||
|         } |  | ||||||
|     }; |  | ||||||
|      |  | ||||||
|     function findGroup(group, parentID) { |  | ||||||
|         // Only searching in groups |  | ||||||
|         if(group.isConnection) |  | ||||||
|             return; |  | ||||||
|          |  | ||||||
|         if(group.identifier === parentID) |  | ||||||
|             return group; |  | ||||||
|          |  | ||||||
|         for(var i = 0; i < group.children.length; i++) { |  | ||||||
|             var child = group.children[i]; |  | ||||||
|             var foundGroup = findGroup(child, parentID); |  | ||||||
|             if(foundGroup) return foundGroup; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|          |  | ||||||
|      |  | ||||||
|     $scope.protocols = {}; |     $scope.protocols = {}; | ||||||
|      |      | ||||||
|     // Get the protocol information from the server and copy it into the scope |     // Get the protocol information from the server and copy it into the scope | ||||||
|     protocolService.getProtocols().success(function fetchProtocols(protocols) { |     protocolService.getProtocols().success(function fetchProtocols(protocols) { | ||||||
|         angular.extend($scope.protocols, protocols); |         $scope.protocols = protocols; | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     /** |     // Expose object edit functions to group list template | ||||||
|      * Toggle the open/closed status of the connectionGroup. |     $scope.groupListContext = { | ||||||
|      *  |      | ||||||
|      * @param {object} connectionGroup The connection group to toggle. |         /** | ||||||
|      */ |          * Open a modal to edit the given connection. | ||||||
|     $scope.toggleExpanded = function toggleExpanded(connectionGroup) { |          *   | ||||||
|         connectionGroup.expanded = !connectionGroup.expanded; |          * @param {Connection} connection | ||||||
|  |          *     The connection to edit. | ||||||
|  |          */ | ||||||
|  |         editConnection : function editConnection(connection) { | ||||||
|  |             connectionEditModal.activate({ | ||||||
|  |                 connection : connection,  | ||||||
|  |                 protocols  : $scope.protocols, | ||||||
|  |                 rootGroup  : $scope.rootGroup | ||||||
|  |             }); | ||||||
|  |         }, | ||||||
|  |  | ||||||
|  |         /** | ||||||
|  |          * Open a modal to edit the given connection group. | ||||||
|  |          *   | ||||||
|  |          * @param {ConnectionGroup} connectionGroup | ||||||
|  |          *     The connection group to edit. | ||||||
|  |          */ | ||||||
|  |         editConnectionGroup : function editConnectionGroup(connectionGroup) { | ||||||
|  |             connectionGroupEditModal.activate({ | ||||||
|  |                 connectionGroup : connectionGroup,  | ||||||
|  |                 rootGroup       : $scope.rootGroup | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  |  | ||||||
|     }; |     }; | ||||||
|      |      | ||||||
|     /** |     /** | ||||||
|      * Open a modal to edit the connection. |      * Open a modal to create a new connection. | ||||||
|      *   |  | ||||||
|      * @param {object} connection The connection to edit. |  | ||||||
|      */ |  | ||||||
|     $scope.editConnection = function editConnection(connection) { |  | ||||||
|         connectionEditModal.activate( |  | ||||||
|         { |  | ||||||
|             connection : connection,  |  | ||||||
|             protocols  : $scope.protocols, |  | ||||||
|             moveItem   : $scope.moveItem, |  | ||||||
|             rootGroup  : $scope.rootGroup |  | ||||||
|         }); |  | ||||||
|     }; |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * Open a modal to edit a new connection. |  | ||||||
|      */ |      */ | ||||||
|     $scope.newConnection = function newConnection() { |     $scope.newConnection = function newConnection() { | ||||||
|         connectionEditModal.activate( |         connectionEditModal.activate( | ||||||
|         { |         { | ||||||
|             connection : {},  |             connection : {},  | ||||||
|             protocols  : $scope.protocols, |             protocols  : $scope.protocols, | ||||||
|             moveItem   : $scope.moveItem, |  | ||||||
|             rootGroup  : $scope.rootGroup |             rootGroup  : $scope.rootGroup | ||||||
|         }); |         }); | ||||||
|     }; |     }; | ||||||
|      |      | ||||||
|     /** |     /** | ||||||
|      * Open a modal to edit a new connection group. |      * Open a modal to create a new connection group. | ||||||
|      */ |      */ | ||||||
|     $scope.newConnectionGroup = function newConnectionGroup() { |     $scope.newConnectionGroup = function newConnectionGroup() { | ||||||
|         connectionGroupEditModal.activate( |         connectionGroupEditModal.activate( | ||||||
|         { |         { | ||||||
|             connectionGroup : {},  |             connectionGroup : {},  | ||||||
|             moveItem        : $scope.moveItem, |  | ||||||
|             rootGroup       : $scope.rootGroup |  | ||||||
|         }); |  | ||||||
|     }; |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * Open a modal to edit the connection group. |  | ||||||
|      *   |  | ||||||
|      * @param {object} connection The connection group to edit. |  | ||||||
|      */ |  | ||||||
|     $scope.editConnectionGroup = function editConnectionGroup(connectionGroup) { |  | ||||||
|         connectionGroupEditModal.activate( |  | ||||||
|         { |  | ||||||
|             connectionGroup : connectionGroup,  |  | ||||||
|             moveItem        : $scope.moveItem, |  | ||||||
|             rootGroup       : $scope.rootGroup |             rootGroup       : $scope.rootGroup | ||||||
|         }); |         }); | ||||||
|     }; |     }; | ||||||
|   | |||||||
| @@ -30,63 +30,101 @@ angular.module('manage').directive('locationChooser', [function locationChooser( | |||||||
|         // Element only |         // Element only | ||||||
|         restrict: 'E', |         restrict: 'E', | ||||||
|         replace: true, |         replace: true, | ||||||
|  |  | ||||||
|         scope: { |         scope: { | ||||||
|             item: '=item', |  | ||||||
|             root: '=root', |             /** | ||||||
|  |              * The root connection group of the connection group hierarchy to | ||||||
|  |              * display. | ||||||
|  |              * | ||||||
|  |              * @type ConnectionGroup | ||||||
|  |              */ | ||||||
|  |             rootGroup : '=', | ||||||
|  |  | ||||||
|  |             /** | ||||||
|  |              * The unique identifier of the currently-selected connection | ||||||
|  |              * group. If not specified, the root group will be used. | ||||||
|  |              * | ||||||
|  |              * @type String | ||||||
|  |              */ | ||||||
|  |             value : '=' | ||||||
|  |  | ||||||
|         }, |         }, | ||||||
|  |  | ||||||
|         templateUrl: 'app/manage/templates/locationChooser.html', |         templateUrl: 'app/manage/templates/locationChooser.html', | ||||||
|         controller: ['$scope', '$injector', function locationChooserController($scope, $injector) { |         controller: ['$scope', function locationChooserController($scope) { | ||||||
|             // The dropdown should start closed |  | ||||||
|             $scope.showDropDown = false; |  | ||||||
|  |  | ||||||
|             // Map of ID to name for all connection groups |             /** | ||||||
|             $scope.connectionGroupNameMap = {}; |              * Map of unique identifiers to their corresponding connection | ||||||
|  |              * groups. | ||||||
|  |              * | ||||||
|  |              * @type Object.<String, GroupListItem> | ||||||
|  |              */ | ||||||
|  |             var connectionGroups = {}; | ||||||
|  |  | ||||||
|             // Set up the group for display and search |             var mapConnectionGroups = function mapConnectionGroups(group) { | ||||||
|             mapConnectionGroupNames($scope.root); |  | ||||||
|             $scope.connectionGroups = [$scope.root]; |  | ||||||
|  |  | ||||||
|             // Should be in the root group by default |                 // Map given group | ||||||
|             if(!$scope.item.parentIdentifier) |                 connectionGroups[group.identifier] = group; | ||||||
|                 $scope.item.parentIdentifier = $scope.root.parentIdentifier; |  | ||||||
|  |  | ||||||
|             setCurrentParentName(); |                 // Map all child groups | ||||||
|  |                 group.childConnectionGroups.forEach(mapConnectionGroups); | ||||||
|  |  | ||||||
|  |             }; | ||||||
|  |  | ||||||
|  |             // Map all known groups | ||||||
|  |             mapConnectionGroups($scope.rootGroup); | ||||||
|  |  | ||||||
|  |             // If no value is specified, default to the root identifier | ||||||
|  |             if (!$scope.value || !($scope.value in connectionGroups)) | ||||||
|  |                 $scope.value = $scope.rootGroup.identifier; | ||||||
|  |  | ||||||
|  |             /** | ||||||
|  |              * Whether the group list menu is currently open. | ||||||
|  |              *  | ||||||
|  |              * @type Boolean | ||||||
|  |              */ | ||||||
|  |             $scope.menuOpen = false; | ||||||
|  |              | ||||||
|  |             /** | ||||||
|  |              * The human-readable name of the currently-chosen connection | ||||||
|  |              * group. | ||||||
|  |              *  | ||||||
|  |              * @type String | ||||||
|  |              */ | ||||||
|  |             $scope.chosenConnectionGroupName = connectionGroups[$scope.value].name;  | ||||||
|  |              | ||||||
|  |             /** | ||||||
|  |              * Toggle the current state of the menu listing connection groups. | ||||||
|  |              * If the menu is currently open, it will be closed. If currently | ||||||
|  |              * closed, it will be opened. | ||||||
|  |              */ | ||||||
|  |             $scope.toggleMenu = function toggleMenu() { | ||||||
|  |                 $scope.menuOpen = !$scope.menuOpen; | ||||||
|  |             }; | ||||||
|  |  | ||||||
|  |             // Expose selection function to group list template | ||||||
|  |             $scope.groupListContext = { | ||||||
|  |                  | ||||||
|  |                 /** | ||||||
|  |                  * Selects the given group item. | ||||||
|  |                  * | ||||||
|  |                  * @param {GroupListItem} item | ||||||
|  |                  *     The chosen item. | ||||||
|  |                  */ | ||||||
|  |                 chooseGroup : function chooseGroup(item) { | ||||||
|  |  | ||||||
|  |                     // Record new parent | ||||||
|  |                     $scope.value = item.identifier; | ||||||
|  |                     $scope.chosenConnectionGroupName = item.name; | ||||||
|  |  | ||||||
|  |                     // Close menu | ||||||
|  |                     $scope.menuOpen = false; | ||||||
|  |  | ||||||
|             // Add the name of all connection groups under group to the group name map |  | ||||||
|             function mapConnectionGroupNames(group) { |  | ||||||
|                 $scope.connectionGroupNameMap[group.identifier] = group.name; |  | ||||||
|                 for(var i = 0; i < group.children.length; i++) { |  | ||||||
|                     var child = group.children[i]; |  | ||||||
|                     if(!child.isConnection) |  | ||||||
|                         mapConnectionGroupNames(child); |  | ||||||
|                 } |                 } | ||||||
|             } |  | ||||||
|  |  | ||||||
|             //Set the current connection group name to the name of the connection group with the currently chosen ID |             }; | ||||||
|             function setCurrentParentName() { |  | ||||||
|                 $scope.currentConnectionGroupName = $scope.connectionGroupNameMap[$scope.item.parentIdentifier]; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             // Watch for changes to the parentID, and update the current name as needed |  | ||||||
|             $scope.currentConnectionGroupName = ""; |  | ||||||
|             $scope.$watch('item.parentIdentifier', function watchParentID() { |  | ||||||
|                 setCurrentParentName(); |  | ||||||
|             }); |  | ||||||
|              |  | ||||||
|             /** |  | ||||||
|              * Toggle the drop down - open or closed. |  | ||||||
|              */ |  | ||||||
|             $scope.toggleDropDown = function toggleDropDown() { |  | ||||||
|                 $scope.showDropDown = !$scope.showDropDown; |  | ||||||
|             } |  | ||||||
|              |  | ||||||
|             /** |  | ||||||
|              * Choose a new parent ID for the item. |  | ||||||
|              * @param {type} parentID The new parentID. |  | ||||||
|              */ |  | ||||||
|             $scope.chooseParentID = function chooseParentID(parentID) { |  | ||||||
|                 $scope.item.parentIdentifier = parentID; |  | ||||||
|             } |  | ||||||
|         }] |         }] | ||||||
|     }; |     }; | ||||||
|      |      | ||||||
|   | |||||||
| @@ -23,5 +23,5 @@ | |||||||
| /** | /** | ||||||
|  * The module for the administration functionality. |  * The module for the administration functionality. | ||||||
|  */ |  */ | ||||||
| angular.module('manage', ['btford.modal', 'groupList', 'rest', 'util']); | angular.module('manage', ['btford.modal', 'groupList', 'rest']); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -0,0 +1,35 @@ | |||||||
|  | <div ng-click="context.editConnection(item.wrappedItem)"> | ||||||
|  |     <!-- | ||||||
|  |        Copyright (C) 2014 Glyptodon LLC | ||||||
|  |  | ||||||
|  |        Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  |        of this software and associated documentation files (the "Software"), to deal | ||||||
|  |        in the Software without restriction, including without limitation the rights | ||||||
|  |        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  |        copies of the Software, and to permit persons to whom the Software is | ||||||
|  |        furnished to do so, subject to the following conditions: | ||||||
|  |  | ||||||
|  |        The above copyright notice and this permission notice shall be included in | ||||||
|  |        all copies or substantial portions of the Software. | ||||||
|  |  | ||||||
|  |        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||||
|  |        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||||
|  |        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||||
|  |        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||||
|  |        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||||
|  |        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||||
|  |        THE SOFTWARE. | ||||||
|  |     --> | ||||||
|  |  | ||||||
|  |     <div class="caption"> | ||||||
|  |  | ||||||
|  |         <!-- Connection icon --> | ||||||
|  |         <div class="protocol"> | ||||||
|  |             <div class="icon type" ng-class="item.protocol"></div> | ||||||
|  |         </div> | ||||||
|  |  | ||||||
|  |         <!-- Connection name --> | ||||||
|  |         <span class="name">{{item.name}}</span> | ||||||
|  |  | ||||||
|  |     </div> | ||||||
|  | </div> | ||||||
| @@ -0,0 +1,25 @@ | |||||||
|  | <span class="name" ng-click="context.editConnectionGroup(item.wrappedItem)"> | ||||||
|  |     <!-- | ||||||
|  |        Copyright (C) 2014 Glyptodon LLC | ||||||
|  |  | ||||||
|  |        Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  |        of this software and associated documentation files (the "Software"), to deal | ||||||
|  |        in the Software without restriction, including without limitation the rights | ||||||
|  |        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  |        copies of the Software, and to permit persons to whom the Software is | ||||||
|  |        furnished to do so, subject to the following conditions: | ||||||
|  |  | ||||||
|  |        The above copyright notice and this permission notice shall be included in | ||||||
|  |        all copies or substantial portions of the Software. | ||||||
|  |  | ||||||
|  |        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||||
|  |        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||||
|  |        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||||
|  |        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||||
|  |        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||||
|  |        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||||
|  |        THE SOFTWARE. | ||||||
|  |     --> | ||||||
|  |  | ||||||
|  |     {{item.name}} | ||||||
|  | </span> | ||||||
| @@ -50,7 +50,7 @@ THE SOFTWARE. | |||||||
|                   <th>{{'manage.edit.connection.location' | translate}}</th> |                   <th>{{'manage.edit.connection.location' | translate}}</th> | ||||||
|  |  | ||||||
|                   <td> |                   <td> | ||||||
|                     <location-chooser item="connection" root="rootGroup"/> |                     <location-chooser value="connection.parentIdentifier" root-group="rootGroup"/> | ||||||
|                   </td> |                   </td> | ||||||
|                 </tr> |                 </tr> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -50,7 +50,7 @@ THE SOFTWARE. | |||||||
|                   <th>{{'manage.edit.connectionGroup.location' | translate}}</th> |                   <th>{{'manage.edit.connectionGroup.location' | translate}}</th> | ||||||
|  |  | ||||||
|                   <td> |                   <td> | ||||||
|                     <location-chooser item="connectionGroup" root="rootGroup"/> |                     <location-chooser value="connectionGroup.parentIdentifier" root-group="rootGroup"/> | ||||||
|                   </td> |                   </td> | ||||||
|                 </tr> |                 </tr> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -21,26 +21,15 @@ | |||||||
|     THE SOFTWARE. |     THE SOFTWARE. | ||||||
|     --> |     --> | ||||||
|  |  | ||||||
|     <script type="text/ng-template" id="nestedGroupSelect.html"> |  | ||||||
|         <div class="group" ng-show="!item.isConnection"> |  | ||||||
|             <div class="caption"> |  | ||||||
|                 <div class="icon group type" ng-click="item.expanded = !item.expanded" ng-class="{expanded: item.expanded, empty: !item.children.length, balancer: item.balancer && !item.children.length}"></div> |  | ||||||
|                 <span class="name" ng-click="chooseParentID(item.identifier); toggleDropDown()">{{item.name}}</span> |  | ||||||
|             </div> |  | ||||||
|             <div class="children" ng-show="item.expanded"> |  | ||||||
|                 <div class="list-item" ng-repeat="item in item.children | orderBy : 'name'" ng-include="'nestedGroupSelect.html'"> |  | ||||||
|             </div> |  | ||||||
|         </div> |  | ||||||
|     </script> |  | ||||||
|  |  | ||||||
|     <!-- Open the dropdown --> |     <!-- Open the dropdown --> | ||||||
|     <div ng-click="toggleDropDown()" class="location">{{currentConnectionGroupName}}</div> |     <div ng-click="toggleMenu()" class="location">{{chosenConnectionGroupName}}</div> | ||||||
|  |  | ||||||
|     <div ng-show="showDropDown" class="dropdown"> |      | ||||||
|       <div class="group-view"> |     <div ng-show="menuOpen" class="dropdown"> | ||||||
|         <div class="list"> |         <guac-group-list | ||||||
|             <div class="list-item" ng-repeat="item in connectionGroups | orderBy : 'name'" ng-include="'nestedGroupSelect.html'"></div> |             context="groupListContext" | ||||||
|         </div> |             show-root-group="true" | ||||||
|       </div> |             connection-group="rootGroup" | ||||||
|  |             connection-group-template="'app/manage/templates/locationChooserConnectionGroup.html'"/> | ||||||
|     </div> |     </div> | ||||||
| </div> | </div> | ||||||
|   | |||||||
| @@ -0,0 +1,25 @@ | |||||||
|  | <span class="name" ng-click="context.chooseGroup(item.wrappedItem)"> | ||||||
|  |     <!-- | ||||||
|  |        Copyright (C) 2014 Glyptodon LLC | ||||||
|  |  | ||||||
|  |        Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  |        of this software and associated documentation files (the "Software"), to deal | ||||||
|  |        in the Software without restriction, including without limitation the rights | ||||||
|  |        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  |        copies of the Software, and to permit persons to whom the Software is | ||||||
|  |        furnished to do so, subject to the following conditions: | ||||||
|  |  | ||||||
|  |        The above copyright notice and this permission notice shall be included in | ||||||
|  |        all copies or substantial portions of the Software. | ||||||
|  |  | ||||||
|  |        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||||
|  |        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||||
|  |        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||||
|  |        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||||
|  |        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||||
|  |        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||||
|  |        THE SOFTWARE. | ||||||
|  |     --> | ||||||
|  |  | ||||||
|  |     {{item.name}} | ||||||
|  | </span> | ||||||
| @@ -63,7 +63,11 @@ THE SOFTWARE. | |||||||
|  |  | ||||||
|         <!-- List of connections and groups this user has access to --> |         <!-- List of connections and groups this user has access to --> | ||||||
|         <div class="connection-list" ng-class="{loading: loadingConnections}"> |         <div class="connection-list" ng-class="{loading: loadingConnections}"> | ||||||
|             <guac-group-list connection-group="rootGroup"/> |             <guac-group-list | ||||||
|  |                 context="groupListContext" | ||||||
|  |                 connection-group="rootGroup" | ||||||
|  |                 connection-template="'app/manage/templates/connection.html'" | ||||||
|  |                 connection-group-template="'app/manage/templates/connectionGroup.html'"/> | ||||||
|         </div> |         </div> | ||||||
|     </div> |     </div> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,56 +0,0 @@ | |||||||
| /* |  | ||||||
|  * Copyright (C) 2014 Glyptodon LLC |  | ||||||
|  * |  | ||||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy |  | ||||||
|  * of this software and associated documentation files (the "Software"), to deal |  | ||||||
|  * in the Software without restriction, including without limitation the rights |  | ||||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |  | ||||||
|  * copies of the Software, and to permit persons to whom the Software is |  | ||||||
|  * furnished to do so, subject to the following conditions: |  | ||||||
|  * |  | ||||||
|  * The above copyright notice and this permission notice shall be included in |  | ||||||
|  * all copies or substantial portions of the Software. |  | ||||||
|  * |  | ||||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |  | ||||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |  | ||||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |  | ||||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |  | ||||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |  | ||||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |  | ||||||
|  * THE SOFTWARE. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * A service to help prepare objects from the REST API for display. |  | ||||||
|  */ |  | ||||||
| angular.module('util').factory('displayObjectPreparationService', [function displayObjectPreparationService() { |  | ||||||
|     var service = {}; |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * Adds properties to the connection that will be useful for display. |  | ||||||
|      *  |  | ||||||
|      * @param {object} connection The connection to add display properties to. |  | ||||||
|      */ |  | ||||||
|     service.prepareConnection = function prepareConnection(connection) { |  | ||||||
|          |  | ||||||
|         // This is a connection |  | ||||||
|         connection.isConnection = true; |  | ||||||
|     }; |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * Adds properties to the connection that will be useful for display. |  | ||||||
|      *  |  | ||||||
|      * @param {object} connectionGroup The connection group to add display properties to. |  | ||||||
|      */ |  | ||||||
|     service.prepareConnectionGroup = function prepareConnectionGroup(connectionGroup) { |  | ||||||
|          |  | ||||||
|         // This is not a connection |  | ||||||
|         connectionGroup.isConnection = false; |  | ||||||
|              |  | ||||||
|         connectionGroup.balancer = connectionGroup.type !== "ORGANIZATIONAL"; |  | ||||||
|         connectionGroup.expanded = false; |  | ||||||
|         connectionGroup.children = []; |  | ||||||
|     }; |  | ||||||
|      |  | ||||||
|     return service; |  | ||||||
| }]); |  | ||||||
| @@ -1,26 +0,0 @@ | |||||||
| /* |  | ||||||
|  * Copyright (C) 2014 Glyptodon LLC |  | ||||||
|  * |  | ||||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy |  | ||||||
|  * of this software and associated documentation files (the "Software"), to deal |  | ||||||
|  * in the Software without restriction, including without limitation the rights |  | ||||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |  | ||||||
|  * copies of the Software, and to permit persons to whom the Software is |  | ||||||
|  * furnished to do so, subject to the following conditions: |  | ||||||
|  * |  | ||||||
|  * The above copyright notice and this permission notice shall be included in |  | ||||||
|  * all copies or substantial portions of the Software. |  | ||||||
|  * |  | ||||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |  | ||||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |  | ||||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |  | ||||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |  | ||||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |  | ||||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |  | ||||||
|  * THE SOFTWARE. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * A module for miscellaneous services and utilities that don't belong elsewhere. |  | ||||||
|  */ |  | ||||||
| angular.module('util', []); |  | ||||||
		Reference in New Issue
	
	Block a user