mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-10-31 09:03:21 +00:00 
			
		
		
		
	GUAC-1406: Add directive for filtering connection group hierarchies.
This commit is contained in:
		| @@ -0,0 +1,212 @@ | ||||
| /* | ||||
|  * Copyright (C) 2015 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 directive which provides a filtering text input field which automatically | ||||
|  * produces a filtered subset of the given connection groups. | ||||
|  */ | ||||
| angular.module('groupList').directive('guacGroupListFilter', [function guacGroupListFilter() { | ||||
|  | ||||
|     return { | ||||
|         restrict: 'E', | ||||
|         replace: true, | ||||
|         scope: { | ||||
|  | ||||
|             /** | ||||
|              * The property to which a subset of the provided map of connection | ||||
|              * groups will be assigned. | ||||
|              * | ||||
|              * @type Array | ||||
|              */ | ||||
|             filteredConnectionGroups : '=', | ||||
|  | ||||
|             /** | ||||
|              * The placeholder text to display within the filter input field | ||||
|              * when no filter has been provided. | ||||
|              *  | ||||
|              * @type String | ||||
|              */ | ||||
|             placeholder : '&', | ||||
|  | ||||
|             /** | ||||
|              * The connection groups to filter, as a map of data source | ||||
|              * identifier to corresponding root group. A subset of this map | ||||
|              * will be exposed as filteredConnectionGroups. | ||||
|              * | ||||
|              * @type Object.<String, ConnectionGroup> | ||||
|              */ | ||||
|             connectionGroups : '&', | ||||
|  | ||||
|             /** | ||||
|              * An array of expressions to filter against for each connection in | ||||
|              * the hierarchy of connections and groups in the provided map. | ||||
|              * These expressions must be Angular expressions which resolve to | ||||
|              * properties on the connections in the provided map. | ||||
|              * | ||||
|              * @type String[] | ||||
|              */ | ||||
|             connectionProperties : '&', | ||||
|  | ||||
|             /** | ||||
|              * An array of expressions to filter against for each connection group | ||||
|              * in the hierarchy of connections and groups in the provided map. | ||||
|              * These expressions must be Angular expressions which resolve to | ||||
|              * properties on the connection groups in the provided map. | ||||
|              * | ||||
|              * @type String[] | ||||
|              */ | ||||
|             connectionGroupProperties : '&' | ||||
|  | ||||
|         }, | ||||
|  | ||||
|         templateUrl: 'app/groupList/templates/guacGroupListFilter.html', | ||||
|         controller: ['$scope', '$injector', function guacGroupListFilterController($scope, $injector) { | ||||
|  | ||||
|             // Required types | ||||
|             var ConnectionGroup = $injector.get('ConnectionGroup'); | ||||
|             var FilterPattern   = $injector.get('FilterPattern'); | ||||
|  | ||||
|             /** | ||||
|              * The pattern object to use when filtering connections. | ||||
|              * | ||||
|              * @type FilterPattern | ||||
|              */ | ||||
|             var connectionFilterPattern = new FilterPattern($scope.connectionProperties()); | ||||
|  | ||||
|             /** | ||||
|              * The pattern object to use when filtering connection groups. | ||||
|              * | ||||
|              * @type FilterPattern | ||||
|              */ | ||||
|             var connectionGroupFilterPattern = new FilterPattern($scope.connectionGroupProperties()); | ||||
|  | ||||
|             /** | ||||
|              * The filter search string to use to restrict the displayed | ||||
|              * connection groups. | ||||
|              * | ||||
|              * @type String | ||||
|              */ | ||||
|             $scope.searchString = null; | ||||
|  | ||||
|             /** | ||||
|              * Flattens the connection group hierarchy of the given connection | ||||
|              * group such that all descendants are copied as immediate | ||||
|              * children. The hierarchy of nested connection groups is otherwise | ||||
|              * completely preserved. A connection or connection group nested | ||||
|              * two or more levels deep within the hierarchy will thus appear | ||||
|              * within the returned connection group in two places: in its | ||||
|              * original location AND as an immediate child. | ||||
|              * | ||||
|              * @param {ConnectionGroup} connectionGroup | ||||
|              *     The connection group whose descendents should be copied as | ||||
|              *     first-level children. | ||||
|              * | ||||
|              * @returns {ConnectionGroup} | ||||
|              *     A new connection group completely identical to the provided | ||||
|              *     connection group, except that absolutely all descendents | ||||
|              *     have been copied into the first level of children. | ||||
|              */ | ||||
|             var flattenConnectionGroup = function flattenConnectionGroup(connectionGroup) { | ||||
|  | ||||
|                 // Replace connection group with shallow copy | ||||
|                 connectionGroup = new ConnectionGroup(connectionGroup); | ||||
|  | ||||
|                 // Ensure child arrays are defined and independent copies | ||||
|                 connectionGroup.childConnections = angular.copy(connectionGroup.childConnections) || []; | ||||
|                 connectionGroup.childConnectionGroups = angular.copy(connectionGroup.childConnectionGroups) || []; | ||||
|  | ||||
|                 // Flatten all children to the top-level group | ||||
|                 angular.forEach(connectionGroup.childConnectionGroups, function flattenChild(child) { | ||||
|  | ||||
|                     var flattenedChild = flattenConnectionGroup(child); | ||||
|  | ||||
|                     // Merge all child connections | ||||
|                     Array.prototype.push.apply( | ||||
|                         connectionGroup.childConnections, | ||||
|                         flattenedChild.childConnections | ||||
|                     ); | ||||
|  | ||||
|                     // Merge all child connection groups | ||||
|                     Array.prototype.push.apply( | ||||
|                         connectionGroup.childConnectionGroups, | ||||
|                         flattenedChild.childConnectionGroups | ||||
|                     ); | ||||
|  | ||||
|                 }); | ||||
|  | ||||
|                 return connectionGroup; | ||||
|  | ||||
|             }; | ||||
|  | ||||
|             /** | ||||
|              * Applies the current filter predicate, filtering all provided | ||||
|              * connection groups and storing the result in | ||||
|              * filteredConnectionGroups. | ||||
|              */ | ||||
|             var updateFilteredConnectionGroups = function updateFilteredConnectionGroups() { | ||||
|  | ||||
|                 // Do not apply any filtering (and do not flatten) if no | ||||
|                 // search string is provided | ||||
|                 if (!$scope.searchString) { | ||||
|                     $scope.filteredConnectionGroups = $scope.connectionGroups() || {}; | ||||
|                     return; | ||||
|                 } | ||||
|  | ||||
|                 // Clear all current filtered groups | ||||
|                 $scope.filteredConnectionGroups = {}; | ||||
|  | ||||
|                 // Re-filter any provided groups | ||||
|                 var connectionGroups = $scope.connectionGroups(); | ||||
|                 if (connectionGroups) { | ||||
|                     angular.forEach(connectionGroups, function updateFilteredConnectionGroup(connectionGroup, dataSource) { | ||||
|  | ||||
|                         // Flatten hierarchy of connection group | ||||
|                         var filteredGroup = flattenConnectionGroup(connectionGroup); | ||||
|  | ||||
|                         // Filter all direct children | ||||
|                         filteredGroup.childConnections = filteredGroup.childConnections.filter(connectionFilterPattern.predicate); | ||||
|                         filteredGroup.childConnectionGroups = filteredGroup.childConnectionGroups.filter(connectionGroupFilterPattern.predicate); | ||||
|  | ||||
|                         // Store now-filtered root | ||||
|                         $scope.filteredConnectionGroups[dataSource] = filteredGroup; | ||||
|  | ||||
|                     }); | ||||
|                 } | ||||
|  | ||||
|             }; | ||||
|  | ||||
|             // Recompile and refilter when pattern is changed | ||||
|             $scope.$watch('searchString', function searchStringChanged(searchString) { | ||||
|                 connectionFilterPattern.compile(searchString); | ||||
|                 connectionGroupFilterPattern.compile(searchString); | ||||
|                 updateFilteredConnectionGroups(); | ||||
|             }); | ||||
|  | ||||
|             // Refilter when items change | ||||
|             $scope.$watchCollection($scope.connectionGroups, function itemsChanged() { | ||||
|                 updateFilteredConnectionGroups(); | ||||
|             }); | ||||
|  | ||||
|         }] | ||||
|  | ||||
|     }; | ||||
| }]); | ||||
| @@ -0,0 +1,27 @@ | ||||
| <div class="group-list-filter filter"> | ||||
|     <!-- | ||||
|        Copyright (C) 2015 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. | ||||
|     --> | ||||
|  | ||||
|     <!-- Filter string --> | ||||
|     <input class="search-string" placeholder="{{placeholder()}}" type="text" ng-model="searchString"/> | ||||
|  | ||||
| </div> | ||||
		Reference in New Issue
	
	Block a user