mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-10-31 00:53:21 +00:00 
			
		
		
		
	GUAC-586: Restore management of active sessions.
This commit is contained in:
		| @@ -44,10 +44,21 @@ angular.module('settings').directive('guacSettingsSessions', [function guacSetti | |||||||
|             // Required services |             // Required services | ||||||
|             var $filter                 = $injector.get('$filter'); |             var $filter                 = $injector.get('$filter'); | ||||||
|             var $translate              = $injector.get('$translate'); |             var $translate              = $injector.get('$translate'); | ||||||
|  |             var $q                      = $injector.get('$q'); | ||||||
|             var activeConnectionService = $injector.get('activeConnectionService'); |             var activeConnectionService = $injector.get('activeConnectionService'); | ||||||
|  |             var authenticationService   = $injector.get('authenticationService'); | ||||||
|             var connectionGroupService  = $injector.get('connectionGroupService'); |             var connectionGroupService  = $injector.get('connectionGroupService'); | ||||||
|  |             var dataSourceService       = $injector.get('dataSourceService'); | ||||||
|             var guacNotification        = $injector.get('guacNotification'); |             var guacNotification        = $injector.get('guacNotification'); | ||||||
|  |  | ||||||
|  |             /** | ||||||
|  |              * The identifiers of all data sources accessible by the current | ||||||
|  |              * user. | ||||||
|  |              * | ||||||
|  |              * @type String[] | ||||||
|  |              */ | ||||||
|  |             var dataSources = authenticationService.getAvailableDataSources(); | ||||||
|  |  | ||||||
|             /** |             /** | ||||||
|              * The ActiveConnectionWrappers of all active sessions accessible |              * The ActiveConnectionWrappers of all active sessions accessible | ||||||
|              * by the current user, or null if the active sessions have not yet |              * by the current user, or null if the active sessions have not yet | ||||||
| @@ -83,20 +94,22 @@ angular.module('settings').directive('guacSettingsSessions', [function guacSetti | |||||||
|             ]; |             ]; | ||||||
|  |  | ||||||
|             /** |             /** | ||||||
|              * All active connections, if known, or null if active connections |              * All active connections, if known, grouped by corresponding data | ||||||
|              * have not yet been loaded. |              * source identifier, or null if active connections have not yet | ||||||
|  |              * been loaded. | ||||||
|              * |              * | ||||||
|              * @type ActiveConnection |              * @type Object.<String, Object.<String, ActiveConnection>> | ||||||
|              */ |              */ | ||||||
|             var activeConnections = null; |             var allActiveConnections = null; | ||||||
|  |  | ||||||
|             /** |             /** | ||||||
|              * Map of all visible connections by object identifier, or null if |              * Map of all visible connections by data source identifier and | ||||||
|              * visible connections have not yet been loaded. |              * object identifier, or null if visible connections have not yet | ||||||
|  |              * been loaded. | ||||||
|              * |              * | ||||||
|              * @type Object.<String, Connection> |              * @type Object.<String, Object.<String, Connection>> | ||||||
|              */ |              */ | ||||||
|             var connections = null; |             var allConnections = null; | ||||||
|  |  | ||||||
|             /** |             /** | ||||||
|              * The date format for use for session-related dates. |              * The date format for use for session-related dates. | ||||||
| @@ -107,24 +120,28 @@ angular.module('settings').directive('guacSettingsSessions', [function guacSetti | |||||||
|  |  | ||||||
|             /** |             /** | ||||||
|              * Map of all currently-selected active connection wrappers by |              * Map of all currently-selected active connection wrappers by | ||||||
|              * identifier. |              * data source and identifier. | ||||||
|              *  |              *  | ||||||
|              * @type Object.<String, ActiveConnectionWrapper> |              * @type Object.<String, Object.<String, ActiveConnectionWrapper>> | ||||||
|              */ |              */ | ||||||
|             var selectedWrappers = {}; |             var allSelectedWrappers = {}; | ||||||
|  |  | ||||||
|             /** |             /** | ||||||
|              * Adds the given connection to the internal set of visible |              * Adds the given connection to the internal set of visible | ||||||
|              * connections. |              * connections. | ||||||
|              *  |              * | ||||||
|  |              * @param {String} dataSource | ||||||
|  |              *     The identifier of the data source associated with the given | ||||||
|  |              *     connection. | ||||||
|  |              * | ||||||
|              * @param {Connection} connection |              * @param {Connection} connection | ||||||
|              *     The connection to add to the internal set of visible |              *     The connection to add to the internal set of visible | ||||||
|              *     connections. |              *     connections. | ||||||
|              */ |              */ | ||||||
|             var addConnection = function addConnection(connection) { |             var addConnection = function addConnection(dataSource, connection) { | ||||||
|  |  | ||||||
|                 // Add given connection to set of visible connections |                 // Add given connection to set of visible connections | ||||||
|                 connections[connection.identifier] = connection; |                 allConnections[dataSource][connection.identifier] = connection; | ||||||
|  |  | ||||||
|             }; |             }; | ||||||
|  |  | ||||||
| @@ -132,19 +149,25 @@ angular.module('settings').directive('guacSettingsSessions', [function guacSetti | |||||||
|              * Adds all descendant connections of the given connection group to |              * Adds all descendant connections of the given connection group to | ||||||
|              * the internal set of connections. |              * the internal set of connections. | ||||||
|              *  |              *  | ||||||
|  |              * @param {String} dataSource | ||||||
|  |              *     The identifier of the data source associated with the given | ||||||
|  |              *     connection group. | ||||||
|  |              * | ||||||
|              * @param {ConnectionGroup} connectionGroup |              * @param {ConnectionGroup} connectionGroup | ||||||
|              *     The connection group whose descendant connections should be |              *     The connection group whose descendant connections should be | ||||||
|              *     added to the internal set of connections. |              *     added to the internal set of connections. | ||||||
|              */ |              */ | ||||||
|             var addDescendantConnections = function addDescendantConnections(connectionGroup) { |             var addDescendantConnections = function addDescendantConnections(dataSource, connectionGroup) { | ||||||
|  |  | ||||||
|                 // Add all child connections |                 // Add all child connections | ||||||
|                 if (connectionGroup.childConnections) |                 angular.forEach(connectionGroup.childConnections, function addConnectionForDataSource(connection) { | ||||||
|                     connectionGroup.childConnections.forEach(addConnection); |                     addConnection(dataSource, connection); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|                 // Add all child connection groups |                 // Add all child connection groups | ||||||
|                 if (connectionGroup.childConnectionGroups) |                 angular.forEach(connectionGroup.childConnectionGroups, function addConnectionGroupForDataSource(connectionGroup) { | ||||||
|                     connectionGroup.childConnectionGroups.forEach(addDescendantConnections); |                     addDescendantConnections(dataSource, connectionGroup); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|             }; |             }; | ||||||
|  |  | ||||||
| @@ -153,50 +176,66 @@ angular.module('settings').directive('guacSettingsSessions', [function guacSetti | |||||||
|              * within the scope. If required data has not yet finished loading, |              * within the scope. If required data has not yet finished loading, | ||||||
|              * this function has no effect. |              * this function has no effect. | ||||||
|              */ |              */ | ||||||
|             var wrapActiveConnections = function wrapActiveConnections() { |             var wrapAllActiveConnections = function wrapAllActiveConnections() { | ||||||
|  |  | ||||||
|                 // Abort if not all required data is available |                 // Abort if not all required data is available | ||||||
|                 if (!activeConnections || !connections || !sessionDateFormat) |                 if (!allActiveConnections || !allConnections || !sessionDateFormat) | ||||||
|                     return; |                     return; | ||||||
|  |  | ||||||
|                 // Wrap all active connections for sake of display |                 // Wrap all active connections for sake of display | ||||||
|                 $scope.wrappers = []; |                 $scope.wrappers = []; | ||||||
|                 for (var identifier in activeConnections) { |                 angular.forEach(allActiveConnections, function wrapActiveConnections(activeConnections, dataSource) { | ||||||
|  |                     angular.forEach(activeConnections, function wrapActiveConnection(activeConnection, identifier) { | ||||||
|  |  | ||||||
|                     var activeConnection = activeConnections[identifier]; |                         // Retrieve corresponding connection | ||||||
|                     var connection = connections[activeConnection.connectionIdentifier]; |                         var connection = allConnections[dataSource][activeConnection.connectionIdentifier]; | ||||||
|  |  | ||||||
|                     $scope.wrappers.push(new ActiveConnectionWrapper( |                         // Add wrapper | ||||||
|                         connection.name, |                         $scope.wrappers.push(new ActiveConnectionWrapper({ | ||||||
|                         $filter('date')(activeConnection.startDate, sessionDateFormat), |                             dataSource       : dataSource, | ||||||
|                         activeConnection |                             name             : connection.name, | ||||||
|                     ));  |                             startDate        : $filter('date')(activeConnection.startDate, sessionDateFormat), | ||||||
|  |                             activeConnection : activeConnection | ||||||
|  |                         })); | ||||||
|  |  | ||||||
|                 } |                     }); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|             }; |             }; | ||||||
|  |  | ||||||
|             // Retrieve all connections  |             // Retrieve all connections  | ||||||
|             connectionGroupService.getConnectionGroupTree(ConnectionGroup.ROOT_IDENTIFIER) |             dataSourceService.apply( | ||||||
|             .success(function connectionGroupReceived(retrievedRootGroup) { |                 connectionGroupService.getConnectionGroupTree, | ||||||
|  |                 dataSources, | ||||||
|  |                 ConnectionGroup.ROOT_IDENTIFIER | ||||||
|  |             ) | ||||||
|  |             .then(function connectionGroupsReceived(rootGroups) { | ||||||
|  |  | ||||||
|                 // Load connections from retrieved group tree |                 allConnections = {}; | ||||||
|                 connections = {}; |  | ||||||
|                 addDescendantConnections(retrievedRootGroup); |                 // Load connections from each received root group | ||||||
|  |                 angular.forEach(rootGroups, function connectionGroupReceived(rootGroup, dataSource) { | ||||||
|  |                     allConnections[dataSource] = {}; | ||||||
|  |                     addDescendantConnections(dataSource, rootGroup); | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|                 // Attempt to produce wrapped list of active connections |                 // Attempt to produce wrapped list of active connections | ||||||
|                 wrapActiveConnections(); |                 wrapAllActiveConnections(); | ||||||
|  |  | ||||||
|             }); |             }); | ||||||
|              |              | ||||||
|             // Query active sessions |             // Query active sessions | ||||||
|             activeConnectionService.getActiveConnections().success(function sessionsRetrieved(retrievedActiveConnections) { |             dataSourceService.apply( | ||||||
|  |                 activeConnectionService.getActiveConnections, | ||||||
|  |                 dataSources | ||||||
|  |             ) | ||||||
|  |             .then(function sessionsRetrieved(retrievedActiveConnections) { | ||||||
|  |  | ||||||
|                 // Store received list |                 // Store received map of active connections | ||||||
|                 activeConnections = retrievedActiveConnections; |                 allActiveConnections = retrievedActiveConnections; | ||||||
|  |  | ||||||
|                 // Attempt to produce wrapped list of active connections |                 // Attempt to produce wrapped list of active connections | ||||||
|                 wrapActiveConnections(); |                 wrapAllActiveConnections(); | ||||||
|  |  | ||||||
|             }); |             }); | ||||||
|  |  | ||||||
| @@ -207,7 +246,7 @@ angular.module('settings').directive('guacSettingsSessions', [function guacSetti | |||||||
|                 sessionDateFormat = retrievedSessionDateFormat; |                 sessionDateFormat = retrievedSessionDateFormat; | ||||||
|  |  | ||||||
|                 // Attempt to produce wrapped list of active connections |                 // Attempt to produce wrapped list of active connections | ||||||
|                 wrapActiveConnections(); |                 wrapAllActiveConnections(); | ||||||
|  |  | ||||||
|             }); |             }); | ||||||
|  |  | ||||||
| @@ -219,10 +258,7 @@ angular.module('settings').directive('guacSettingsSessions', [function guacSetti | |||||||
|              *     to be useful, false otherwise. |              *     to be useful, false otherwise. | ||||||
|              */ |              */ | ||||||
|             $scope.isLoaded = function isLoaded() { |             $scope.isLoaded = function isLoaded() { | ||||||
|  |                 return $scope.wrappers !== null; | ||||||
|                 return $scope.wrappers          !== null |  | ||||||
|                     && $scope.sessionDateFormat !== null; |  | ||||||
|  |  | ||||||
|             }; |             }; | ||||||
|  |  | ||||||
|             /** |             /** | ||||||
| @@ -259,7 +295,7 @@ angular.module('settings').directive('guacSettingsSessions', [function guacSetti | |||||||
|                 className   : "danger", |                 className   : "danger", | ||||||
|                 // Handle action |                 // Handle action | ||||||
|                 callback    : function deleteCallback() { |                 callback    : function deleteCallback() { | ||||||
|                     deleteSessionsImmediately(); |                     deleteAllSessionsImmediately(); | ||||||
|                     guacNotification.showStatus(false); |                     guacNotification.showStatus(false); | ||||||
|                 } |                 } | ||||||
|             }; |             }; | ||||||
| @@ -268,24 +304,36 @@ angular.module('settings').directive('guacSettingsSessions', [function guacSetti | |||||||
|              * Immediately deletes the selected sessions, without prompting the |              * Immediately deletes the selected sessions, without prompting the | ||||||
|              * user for confirmation. |              * user for confirmation. | ||||||
|              */ |              */ | ||||||
|             var deleteSessionsImmediately = function deleteSessionsImmediately() { |             var deleteAllSessionsImmediately = function deleteAllSessionsImmediately() { | ||||||
|  |  | ||||||
|                 // Perform deletion |                 var deletionRequests = []; | ||||||
|                 activeConnectionService.deleteActiveConnections(Object.keys(selectedWrappers)) |  | ||||||
|                 .success(function activeConnectionsDeleted() { |                 // Perform deletion for each relevant data source | ||||||
|  |                 angular.forEach(allSelectedWrappers, function deleteSessionsImmediately(selectedWrappers, dataSource) { | ||||||
|  |  | ||||||
|  |                     // Delete sessions, if any are selected | ||||||
|  |                     var identifiers = Object.keys(selectedWrappers); | ||||||
|  |                     if (identifiers.length) | ||||||
|  |                         deletionRequests.push(activeConnectionService.deleteActiveConnections(dataSource, identifiers)); | ||||||
|  |  | ||||||
|  |                 }); | ||||||
|  |  | ||||||
|  |                 // Update interface | ||||||
|  |                 $q.all(deletionRequests) | ||||||
|  |                 .then(function activeConnectionsDeleted() { | ||||||
|  |  | ||||||
|                     // Remove deleted connections from wrapper array |                     // Remove deleted connections from wrapper array | ||||||
|                     $scope.wrappers = $scope.wrappers.filter(function activeConnectionStillExists(wrapper) { |                     $scope.wrappers = $scope.wrappers.filter(function activeConnectionStillExists(wrapper) { | ||||||
|                         return !(wrapper.activeConnection.identifier in selectedWrappers); |                         return !(wrapper.activeConnection.identifier in (allSelectedWrappers[wrapper.dataSource] || {})); | ||||||
|                     }); |                     }); | ||||||
|  |  | ||||||
|                     // Clear selection |                     // Clear selection | ||||||
|                     selectedWrappers = {}; |                     allSelectedWrappers = {}; | ||||||
|  |  | ||||||
|                 }) |                 }, | ||||||
|  |  | ||||||
|                 // Notify of any errors |                 // Notify of any errors | ||||||
|                 .error(function activeConnectionDeletionFailed(error) { |                 function activeConnectionDeletionFailed(error) { | ||||||
|                     guacNotification.showStatus({ |                     guacNotification.showStatus({ | ||||||
|                         'className'  : 'error', |                         'className'  : 'error', | ||||||
|                         'title'      : 'SETTINGS_SESSIONS.DIALOG_HEADER_ERROR', |                         'title'      : 'SETTINGS_SESSIONS.DIALOG_HEADER_ERROR', | ||||||
| @@ -318,8 +366,10 @@ angular.module('settings').directive('guacSettingsSessions', [function guacSetti | |||||||
|             $scope.canDeleteSessions = function canDeleteSessions() { |             $scope.canDeleteSessions = function canDeleteSessions() { | ||||||
|  |  | ||||||
|                 // We can delete sessions if at least one is selected |                 // We can delete sessions if at least one is selected | ||||||
|                 for (var identifier in selectedWrappers) |                 for (var dataSource in allSelectedWrappers) { | ||||||
|                     return true; |                     for (var identifier in allSelectedWrappers[dataSource]) | ||||||
|  |                         return true; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|                 return false; |                 return false; | ||||||
|  |  | ||||||
| @@ -334,6 +384,11 @@ angular.module('settings').directive('guacSettingsSessions', [function guacSetti | |||||||
|              */ |              */ | ||||||
|             $scope.wrapperSelectionChange = function wrapperSelectionChange(wrapper) { |             $scope.wrapperSelectionChange = function wrapperSelectionChange(wrapper) { | ||||||
|  |  | ||||||
|  |                 // Get selection map for associated data source, creating if necessary | ||||||
|  |                 var selectedWrappers = allSelectedWrappers[wrapper.dataSource]; | ||||||
|  |                 if (!selectedWrappers) | ||||||
|  |                     selectedWrappers = allSelectedWrappers[wrapper.dataSource] = {}; | ||||||
|  |  | ||||||
|                 // Add wrapper to map if selected |                 // Add wrapper to map if selected | ||||||
|                 if (wrapper.checked) |                 if (wrapper.checked) | ||||||
|                     selectedWrappers[wrapper.activeConnection.identifier] = wrapper; |                     selectedWrappers[wrapper.activeConnection.identifier] = wrapper; | ||||||
|   | |||||||
| @@ -31,44 +31,47 @@ angular.module('settings').factory('ActiveConnectionWrapper', [ | |||||||
|      * properties, such as a checked option. |      * properties, such as a checked option. | ||||||
|      *  |      *  | ||||||
|      * @constructor |      * @constructor | ||||||
|      * @param {String} name |      * @param {ActiveConnectionWrapper|Object} template | ||||||
|      *     The display name of the active connection. |      *     The object whose properties should be copied within the new | ||||||
|      *      |      *     ActiveConnectionWrapper. | ||||||
|      * @param {String} startDate |  | ||||||
|      *     The date and time this session began, pre-formatted for display. |  | ||||||
|      * |  | ||||||
|      * @param {ActiveConnection} activeConnection |  | ||||||
|      *     The ActiveConnection to wrap. |  | ||||||
|      */ |      */ | ||||||
|     var ActiveConnectionWrapper = function ActiveConnectionWrapper(name, startDate, activeConnection) { |     var ActiveConnectionWrapper = function ActiveConnectionWrapper(template) { | ||||||
|  |  | ||||||
|  |         /** | ||||||
|  |          * The identifier of the data source associate dwith the | ||||||
|  |          * ActiveConnection wrapped by this ActiveConnectionWrapper. | ||||||
|  |          * | ||||||
|  |          * @type String | ||||||
|  |          */ | ||||||
|  |         this.dataSource = template.dataSource; | ||||||
|  |  | ||||||
|         /** |         /** | ||||||
|          * The display name of this connection. |          * The display name of this connection. | ||||||
|          * |          * | ||||||
|          * @type String |          * @type String | ||||||
|          */ |          */ | ||||||
|         this.name = name; |         this.name = template.name; | ||||||
|  |  | ||||||
|         /** |         /** | ||||||
|          * The date and time this session began, pre-formatted for display. |          * The date and time this session began, pre-formatted for display. | ||||||
|          * |          * | ||||||
|          * @type String |          * @type String | ||||||
|          */ |          */ | ||||||
|         this.startDate = startDate; |         this.startDate = template.startDate; | ||||||
|  |  | ||||||
|         /** |         /** | ||||||
|          * The wrapped ActiveConnection. |          * The wrapped ActiveConnection. | ||||||
|          * |          * | ||||||
|          * @type ActiveConnection |          * @type ActiveConnection | ||||||
|          */ |          */ | ||||||
|         this.activeConnection = activeConnection; |         this.activeConnection = template.activeConnection; | ||||||
|  |  | ||||||
|         /** |         /** | ||||||
|          * A flag indicating that the active connection has been selected. |          * A flag indicating that the active connection has been selected. | ||||||
|          * |          * | ||||||
|          * @type Boolean |          * @type Boolean | ||||||
|          */ |          */ | ||||||
|         this.checked = false; |         this.checked = template.checked || false; | ||||||
|  |  | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user