mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
GUAC-1053: Create session management tab.
This commit is contained in:
@@ -1,349 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The controller for the user session administration page.
|
||||
*/
|
||||
angular.module('manage').controller('manageSessionsController', ['$scope', '$injector',
|
||||
function manageSessionsController($scope, $injector) {
|
||||
|
||||
// Required types
|
||||
var ActiveConnectionWrapper = $injector.get('ActiveConnectionWrapper');
|
||||
var ConnectionGroup = $injector.get('ConnectionGroup');
|
||||
var SortOrder = $injector.get('SortOrder');
|
||||
|
||||
// Required services
|
||||
var $filter = $injector.get('$filter');
|
||||
var $translate = $injector.get('$translate');
|
||||
var activeConnectionService = $injector.get('activeConnectionService');
|
||||
var authenticationService = $injector.get('authenticationService');
|
||||
var connectionGroupService = $injector.get('connectionGroupService');
|
||||
var guacNotification = $injector.get('guacNotification');
|
||||
var permissionService = $injector.get('permissionService');
|
||||
|
||||
/**
|
||||
* All permissions associated with the current user, or null if the user's
|
||||
* permissions have not yet been loaded.
|
||||
*
|
||||
* @type PermissionSet
|
||||
*/
|
||||
$scope.permissions = null;
|
||||
|
||||
/**
|
||||
* The ActiveConnectionWrappers of all active sessions accessible by the
|
||||
* current user, or null if the active sessions have not yet been loaded.
|
||||
*
|
||||
* @type ActiveConnectionWrapper[]
|
||||
*/
|
||||
$scope.wrappers = null;
|
||||
|
||||
/**
|
||||
* SortOrder instance which maintains the sort order of the visible
|
||||
* connection wrappers.
|
||||
*
|
||||
* @type SortOrder
|
||||
*/
|
||||
$scope.wrapperOrder = new SortOrder([
|
||||
'activeConnection.username',
|
||||
'startDate',
|
||||
'activeConnection.remoteHost',
|
||||
'name'
|
||||
]);
|
||||
|
||||
/**
|
||||
* Array of all wrapper properties that are filterable.
|
||||
*
|
||||
* @type String[]
|
||||
*/
|
||||
$scope.filteredWrapperProperties = [
|
||||
'activeConnection.username',
|
||||
'startDate',
|
||||
'activeConnection.remoteHost',
|
||||
'name'
|
||||
];
|
||||
|
||||
/**
|
||||
* All active connections, if known, or null if active connections have not
|
||||
* yet been loaded.
|
||||
*
|
||||
* @type ActiveConnection
|
||||
*/
|
||||
var activeConnections = null;
|
||||
|
||||
/**
|
||||
* Map of all visible connections by object identifier, or null if visible
|
||||
* connections have not yet been loaded.
|
||||
*
|
||||
* @type Object.<String, Connection>
|
||||
*/
|
||||
var connections = null;
|
||||
|
||||
/**
|
||||
* The date format for use for session-related dates.
|
||||
*
|
||||
* @type String
|
||||
*/
|
||||
var sessionDateFormat = null;
|
||||
|
||||
/**
|
||||
* Map of all currently-selected active connection wrappers by identifier.
|
||||
*
|
||||
* @type Object.<String, ActiveConnectionWrapper>
|
||||
*/
|
||||
var selectedWrappers = {};
|
||||
|
||||
/**
|
||||
* Adds the given connection to the internal set of visible
|
||||
* connections.
|
||||
*
|
||||
* @param {Connection} connection
|
||||
* The connection to add to the internal set of visible connections.
|
||||
*/
|
||||
var addConnection = function addConnection(connection) {
|
||||
|
||||
// Add given connection to set of visible connections
|
||||
connections[connection.identifier] = connection;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds all descendant connections of the given connection group to the
|
||||
* internal set of connections.
|
||||
*
|
||||
* @param {ConnectionGroup} connectionGroup
|
||||
* The connection group whose descendant connections should be added to
|
||||
* the internal set of connections.
|
||||
*/
|
||||
var addDescendantConnections = function addDescendantConnections(connectionGroup) {
|
||||
|
||||
// Add all child connections
|
||||
if (connectionGroup.childConnections)
|
||||
connectionGroup.childConnections.forEach(addConnection);
|
||||
|
||||
// Add all child connection groups
|
||||
if (connectionGroup.childConnectionGroups)
|
||||
connectionGroup.childConnectionGroups.forEach(addDescendantConnections);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Wraps all loaded active connections, storing the resulting array within
|
||||
* the scope. If required data has not yet finished loading, this function
|
||||
* has no effect.
|
||||
*/
|
||||
var wrapActiveConnections = function wrapActiveConnections() {
|
||||
|
||||
// Abort if not all required data is available
|
||||
if (!activeConnections || !connections || !sessionDateFormat)
|
||||
return;
|
||||
|
||||
// Wrap all active connections for sake of display
|
||||
$scope.wrappers = [];
|
||||
for (var identifier in activeConnections) {
|
||||
|
||||
var activeConnection = activeConnections[identifier];
|
||||
var connection = connections[activeConnection.connectionIdentifier];
|
||||
|
||||
$scope.wrappers.push(new ActiveConnectionWrapper(
|
||||
connection.name,
|
||||
$filter('date')(activeConnection.startDate, sessionDateFormat),
|
||||
activeConnection
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Query the user's permissions
|
||||
permissionService.getPermissions(authenticationService.getCurrentUserID())
|
||||
.success(function permissionsReceived(retrievedPermissions) {
|
||||
$scope.permissions = retrievedPermissions;
|
||||
});
|
||||
|
||||
// Retrieve all connections
|
||||
connectionGroupService.getConnectionGroupTree(ConnectionGroup.ROOT_IDENTIFIER)
|
||||
.success(function connectionGroupReceived(retrievedRootGroup) {
|
||||
|
||||
// Load connections from retrieved group tree
|
||||
connections = {};
|
||||
addDescendantConnections(retrievedRootGroup);
|
||||
|
||||
// Attempt to produce wrapped list of active connections
|
||||
wrapActiveConnections();
|
||||
|
||||
});
|
||||
|
||||
// Query active sessions
|
||||
activeConnectionService.getActiveConnections().success(function sessionsRetrieved(retrievedActiveConnections) {
|
||||
|
||||
// Store received list
|
||||
activeConnections = retrievedActiveConnections;
|
||||
|
||||
// Attempt to produce wrapped list of active connections
|
||||
wrapActiveConnections();
|
||||
|
||||
});
|
||||
|
||||
// Get session date format
|
||||
$translate('MANAGE_SESSION.FORMAT_STARTDATE').then(function sessionDateFormatReceived(retrievedSessionDateFormat) {
|
||||
|
||||
// Store received date format
|
||||
sessionDateFormat = retrievedSessionDateFormat;
|
||||
|
||||
// Attempt to produce wrapped list of active connections
|
||||
wrapActiveConnections();
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns whether critical data has completed being loaded.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
* true if enough data has been loaded for the user interface to be
|
||||
* useful, false otherwise.
|
||||
*/
|
||||
$scope.isLoaded = function isLoaded() {
|
||||
|
||||
return $scope.wrappers !== null
|
||||
&& $scope.sessionDateFormat !== null
|
||||
&& $scope.permissions !== null;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* An action to be provided along with the object sent to showStatus which
|
||||
* closes the currently-shown status dialog.
|
||||
*/
|
||||
var ACKNOWLEDGE_ACTION = {
|
||||
name : "MANAGE_SESSION.ACTION_ACKNOWLEDGE",
|
||||
// Handle action
|
||||
callback : function acknowledgeCallback() {
|
||||
guacNotification.showStatus(false);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* An action to be provided along with the object sent to showStatus which
|
||||
* closes the currently-shown status dialog.
|
||||
*/
|
||||
var CANCEL_ACTION = {
|
||||
name : "MANAGE_SESSION.ACTION_CANCEL",
|
||||
// Handle action
|
||||
callback : function cancelCallback() {
|
||||
guacNotification.showStatus(false);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* An action to be provided along with the object sent to showStatus which
|
||||
* immediately deletes the currently selected sessions.
|
||||
*/
|
||||
var DELETE_ACTION = {
|
||||
name : "MANAGE_SESSION.ACTION_DELETE",
|
||||
className : "danger",
|
||||
// Handle action
|
||||
callback : function deleteCallback() {
|
||||
deleteSessionsImmediately();
|
||||
guacNotification.showStatus(false);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Immediately deletes the selected sessions, without prompting the user for
|
||||
* confirmation.
|
||||
*/
|
||||
var deleteSessionsImmediately = function deleteSessionsImmediately() {
|
||||
|
||||
// Perform deletion
|
||||
activeConnectionService.deleteActiveConnections(Object.keys(selectedWrappers))
|
||||
.success(function activeConnectionsDeleted() {
|
||||
|
||||
// Remove deleted connections from wrapper array
|
||||
$scope.wrappers = $scope.wrappers.filter(function activeConnectionStillExists(wrapper) {
|
||||
return !(wrapper.activeConnection.identifier in selectedWrappers);
|
||||
});
|
||||
|
||||
// Clear selection
|
||||
selectedWrappers = {};
|
||||
|
||||
})
|
||||
|
||||
// Notify of any errors
|
||||
.error(function activeConnectionDeletionFailed(error) {
|
||||
guacNotification.showStatus({
|
||||
'className' : 'error',
|
||||
'title' : 'MANAGE_SESSION.DIALOG_HEADER_ERROR',
|
||||
'text' : error.message,
|
||||
'actions' : [ ACKNOWLEDGE_ACTION ]
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete all selected sessions, prompting the user first to confirm that
|
||||
* deletion is desired.
|
||||
*/
|
||||
$scope.deleteSessions = function deleteSessions() {
|
||||
// Confirm deletion request
|
||||
guacNotification.showStatus({
|
||||
'title' : 'MANAGE_SESSION.DIALOG_HEADER_CONFIRM_DELETE',
|
||||
'text' : 'MANAGE_SESSION.TEXT_CONFIRM_DELETE',
|
||||
'actions' : [ DELETE_ACTION, CANCEL_ACTION]
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether the selected sessions can be deleted.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
* true if selected sessions can be deleted, false otherwise.
|
||||
*/
|
||||
$scope.canDeleteSessions = function canDeleteSessions() {
|
||||
|
||||
// We can delete sessions if at least one is selected
|
||||
for (var identifier in selectedWrappers)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Called whenever an active connection wrapper changes selected status.
|
||||
*
|
||||
* @param {ActiveConnectionWrapper} wrapper
|
||||
* The wrapper whose selected status has changed.
|
||||
*/
|
||||
$scope.wrapperSelectionChange = function wrapperSelectionChange(wrapper) {
|
||||
|
||||
// Add wrapper to map if selected
|
||||
if (wrapper.checked)
|
||||
selectedWrappers[wrapper.activeConnection.identifier] = wrapper;
|
||||
|
||||
// Otherwise, remove wrapper from map
|
||||
else
|
||||
delete selectedWrappers[wrapper.activeConnection.identifier];
|
||||
|
||||
};
|
||||
|
||||
}]);
|
@@ -1,86 +0,0 @@
|
||||
<!--
|
||||
Copyright 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.
|
||||
-->
|
||||
|
||||
<div class="view" ng-class="{loading: !isLoaded()}">
|
||||
|
||||
<div class="header">
|
||||
<h2>{{'MANAGE_SESSION.SECTION_HEADER_SESSIONS' | translate}}</h2>
|
||||
<guac-user-menu></guac-user-menu>
|
||||
</div>
|
||||
|
||||
<!-- User Session management -->
|
||||
<div class="settings section sessions">
|
||||
<p>{{'MANAGE_SESSION.HELP_SESSIONS' | translate}}</p>
|
||||
|
||||
<!-- Form action buttons -->
|
||||
<div class="action-buttons">
|
||||
<button class="delete-sessions danger" ng-disabled="!canDeleteSessions()" ng-click="deleteSessions()">{{'MANAGE_SESSION.ACTION_DELETE' | translate}}</button>
|
||||
</div>
|
||||
|
||||
<!-- Session filter -->
|
||||
<guac-filter filtered-items="filteredWrappers" items="wrappers"
|
||||
placeholder="'MANAGE_SESSION.FIELD_PLACEHOLDER_FILTER' | translate"
|
||||
properties="filteredWrapperProperties"></guac-filter>
|
||||
|
||||
<!-- List of current user sessions -->
|
||||
<table class="sorted session-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="select-session"></th>
|
||||
<th guac-sort-order="wrapperOrder" guac-sort-property="'activeConnection.username'">
|
||||
{{'MANAGE_SESSION.TABLE_HEADER_SESSION_USERNAME' | translate}}
|
||||
</th>
|
||||
<th guac-sort-order="wrapperOrder" guac-sort-property="'startDate'">
|
||||
{{'MANAGE_SESSION.TABLE_HEADER_SESSION_STARTDATE' | translate}}
|
||||
</th>
|
||||
<th guac-sort-order="wrapperOrder" guac-sort-property="'activeConnection.remoteHost'">
|
||||
{{'MANAGE_SESSION.TABLE_HEADER_SESSION_REMOTEHOST' | translate}}
|
||||
</th>
|
||||
<th guac-sort-order="wrapperOrder" guac-sort-property="'name'">
|
||||
{{'MANAGE_SESSION.TABLE_HEADER_SESSION_CONNECTION_NAME' | translate}}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="wrapper in wrapperPage" class="session">
|
||||
<td class="select-session">
|
||||
<input ng-change="wrapperSelectionChange(wrapper)" type="checkbox" ng-model="wrapper.checked" />
|
||||
</td>
|
||||
<td>{{wrapper.activeConnection.username}}</td>
|
||||
<td>{{wrapper.startDate}}</td>
|
||||
<td>{{wrapper.activeConnection.remoteHost}}</td>
|
||||
<td>{{wrapper.name}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- Text displayed if no sessions exist -->
|
||||
<p class="placeholder" ng-hide="wrapperPage.length">
|
||||
{{'MANAGE_SESSION.INFO_NO_SESSIONS' | translate}}
|
||||
</p>
|
||||
|
||||
<!-- Pager for session list -->
|
||||
<guac-pager page="wrapperPage" page-size="25"
|
||||
items="filteredWrappers | orderBy : wrapperOrder.predicate"></guac-pager>
|
||||
</div>
|
||||
|
||||
</div>
|
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
* 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 for managing all active Guacamole sessions.
|
||||
*/
|
||||
angular.module('settings').directive('guacManageSessions', [function guacManageSessions() {
|
||||
|
||||
return {
|
||||
// Element only
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
|
||||
scope: {
|
||||
},
|
||||
|
||||
templateUrl: 'app/settings/templates/manageSessions.html',
|
||||
controller: ['$scope', '$injector',
|
||||
function manageSessionsController($scope, $injector) {
|
||||
|
||||
// Required types
|
||||
var ActiveConnectionWrapper = $injector.get('ActiveConnectionWrapper');
|
||||
var ConnectionGroup = $injector.get('ConnectionGroup');
|
||||
var SortOrder = $injector.get('SortOrder');
|
||||
|
||||
// Required services
|
||||
var $filter = $injector.get('$filter');
|
||||
var $translate = $injector.get('$translate');
|
||||
var activeConnectionService = $injector.get('activeConnectionService');
|
||||
var authenticationService = $injector.get('authenticationService');
|
||||
var connectionGroupService = $injector.get('connectionGroupService');
|
||||
var guacNotification = $injector.get('guacNotification');
|
||||
var permissionService = $injector.get('permissionService');
|
||||
|
||||
/**
|
||||
* All permissions associated with the current user, or null if the user's
|
||||
* permissions have not yet been loaded.
|
||||
*
|
||||
* @type PermissionSet
|
||||
*/
|
||||
$scope.permissions = null;
|
||||
|
||||
/**
|
||||
* The ActiveConnectionWrappers of all active sessions accessible by the
|
||||
* current user, or null if the active sessions have not yet been loaded.
|
||||
*
|
||||
* @type ActiveConnectionWrapper[]
|
||||
*/
|
||||
$scope.wrappers = null;
|
||||
|
||||
/**
|
||||
* SortOrder instance which maintains the sort order of the visible
|
||||
* connection wrappers.
|
||||
*
|
||||
* @type SortOrder
|
||||
*/
|
||||
$scope.wrapperOrder = new SortOrder([
|
||||
'activeConnection.username',
|
||||
'startDate',
|
||||
'activeConnection.remoteHost',
|
||||
'name'
|
||||
]);
|
||||
|
||||
/**
|
||||
* Array of all wrapper properties that are filterable.
|
||||
*
|
||||
* @type String[]
|
||||
*/
|
||||
$scope.filteredWrapperProperties = [
|
||||
'activeConnection.username',
|
||||
'startDate',
|
||||
'activeConnection.remoteHost',
|
||||
'name'
|
||||
];
|
||||
|
||||
/**
|
||||
* All active connections, if known, or null if active connections have not
|
||||
* yet been loaded.
|
||||
*
|
||||
* @type ActiveConnection
|
||||
*/
|
||||
var activeConnections = null;
|
||||
|
||||
/**
|
||||
* Map of all visible connections by object identifier, or null if visible
|
||||
* connections have not yet been loaded.
|
||||
*
|
||||
* @type Object.<String, Connection>
|
||||
*/
|
||||
var connections = null;
|
||||
|
||||
/**
|
||||
* The date format for use for session-related dates.
|
||||
*
|
||||
* @type String
|
||||
*/
|
||||
var sessionDateFormat = null;
|
||||
|
||||
/**
|
||||
* Map of all currently-selected active connection wrappers by identifier.
|
||||
*
|
||||
* @type Object.<String, ActiveConnectionWrapper>
|
||||
*/
|
||||
var selectedWrappers = {};
|
||||
|
||||
/**
|
||||
* Adds the given connection to the internal set of visible
|
||||
* connections.
|
||||
*
|
||||
* @param {Connection} connection
|
||||
* The connection to add to the internal set of visible connections.
|
||||
*/
|
||||
var addConnection = function addConnection(connection) {
|
||||
|
||||
// Add given connection to set of visible connections
|
||||
connections[connection.identifier] = connection;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds all descendant connections of the given connection group to the
|
||||
* internal set of connections.
|
||||
*
|
||||
* @param {ConnectionGroup} connectionGroup
|
||||
* The connection group whose descendant connections should be added to
|
||||
* the internal set of connections.
|
||||
*/
|
||||
var addDescendantConnections = function addDescendantConnections(connectionGroup) {
|
||||
|
||||
// Add all child connections
|
||||
if (connectionGroup.childConnections)
|
||||
connectionGroup.childConnections.forEach(addConnection);
|
||||
|
||||
// Add all child connection groups
|
||||
if (connectionGroup.childConnectionGroups)
|
||||
connectionGroup.childConnectionGroups.forEach(addDescendantConnections);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Wraps all loaded active connections, storing the resulting array within
|
||||
* the scope. If required data has not yet finished loading, this function
|
||||
* has no effect.
|
||||
*/
|
||||
var wrapActiveConnections = function wrapActiveConnections() {
|
||||
|
||||
// Abort if not all required data is available
|
||||
if (!activeConnections || !connections || !sessionDateFormat)
|
||||
return;
|
||||
|
||||
// Wrap all active connections for sake of display
|
||||
$scope.wrappers = [];
|
||||
for (var identifier in activeConnections) {
|
||||
|
||||
var activeConnection = activeConnections[identifier];
|
||||
var connection = connections[activeConnection.connectionIdentifier];
|
||||
|
||||
$scope.wrappers.push(new ActiveConnectionWrapper(
|
||||
connection.name,
|
||||
$filter('date')(activeConnection.startDate, sessionDateFormat),
|
||||
activeConnection
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Query the user's permissions
|
||||
permissionService.getPermissions(authenticationService.getCurrentUserID())
|
||||
.success(function permissionsReceived(retrievedPermissions) {
|
||||
$scope.permissions = retrievedPermissions;
|
||||
});
|
||||
|
||||
// Retrieve all connections
|
||||
connectionGroupService.getConnectionGroupTree(ConnectionGroup.ROOT_IDENTIFIER)
|
||||
.success(function connectionGroupReceived(retrievedRootGroup) {
|
||||
|
||||
// Load connections from retrieved group tree
|
||||
connections = {};
|
||||
addDescendantConnections(retrievedRootGroup);
|
||||
|
||||
// Attempt to produce wrapped list of active connections
|
||||
wrapActiveConnections();
|
||||
|
||||
});
|
||||
|
||||
// Query active sessions
|
||||
activeConnectionService.getActiveConnections().success(function sessionsRetrieved(retrievedActiveConnections) {
|
||||
|
||||
// Store received list
|
||||
activeConnections = retrievedActiveConnections;
|
||||
|
||||
// Attempt to produce wrapped list of active connections
|
||||
wrapActiveConnections();
|
||||
|
||||
});
|
||||
|
||||
// Get session date format
|
||||
$translate('MANAGE_SESSION.FORMAT_STARTDATE').then(function sessionDateFormatReceived(retrievedSessionDateFormat) {
|
||||
|
||||
// Store received date format
|
||||
sessionDateFormat = retrievedSessionDateFormat;
|
||||
|
||||
// Attempt to produce wrapped list of active connections
|
||||
wrapActiveConnections();
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns whether critical data has completed being loaded.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
* true if enough data has been loaded for the user interface to be
|
||||
* useful, false otherwise.
|
||||
*/
|
||||
$scope.isLoaded = function isLoaded() {
|
||||
|
||||
return $scope.wrappers !== null
|
||||
&& $scope.sessionDateFormat !== null
|
||||
&& $scope.permissions !== null;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* An action to be provided along with the object sent to showStatus which
|
||||
* closes the currently-shown status dialog.
|
||||
*/
|
||||
var ACKNOWLEDGE_ACTION = {
|
||||
name : "MANAGE_SESSION.ACTION_ACKNOWLEDGE",
|
||||
// Handle action
|
||||
callback : function acknowledgeCallback() {
|
||||
guacNotification.showStatus(false);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* An action to be provided along with the object sent to showStatus which
|
||||
* closes the currently-shown status dialog.
|
||||
*/
|
||||
var CANCEL_ACTION = {
|
||||
name : "MANAGE_SESSION.ACTION_CANCEL",
|
||||
// Handle action
|
||||
callback : function cancelCallback() {
|
||||
guacNotification.showStatus(false);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* An action to be provided along with the object sent to showStatus which
|
||||
* immediately deletes the currently selected sessions.
|
||||
*/
|
||||
var DELETE_ACTION = {
|
||||
name : "MANAGE_SESSION.ACTION_DELETE",
|
||||
className : "danger",
|
||||
// Handle action
|
||||
callback : function deleteCallback() {
|
||||
deleteSessionsImmediately();
|
||||
guacNotification.showStatus(false);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Immediately deletes the selected sessions, without prompting the user for
|
||||
* confirmation.
|
||||
*/
|
||||
var deleteSessionsImmediately = function deleteSessionsImmediately() {
|
||||
|
||||
// Perform deletion
|
||||
activeConnectionService.deleteActiveConnections(Object.keys(selectedWrappers))
|
||||
.success(function activeConnectionsDeleted() {
|
||||
|
||||
// Remove deleted connections from wrapper array
|
||||
$scope.wrappers = $scope.wrappers.filter(function activeConnectionStillExists(wrapper) {
|
||||
return !(wrapper.activeConnection.identifier in selectedWrappers);
|
||||
});
|
||||
|
||||
// Clear selection
|
||||
selectedWrappers = {};
|
||||
|
||||
})
|
||||
|
||||
// Notify of any errors
|
||||
.error(function activeConnectionDeletionFailed(error) {
|
||||
guacNotification.showStatus({
|
||||
'className' : 'error',
|
||||
'title' : 'MANAGE_SESSION.DIALOG_HEADER_ERROR',
|
||||
'text' : error.message,
|
||||
'actions' : [ ACKNOWLEDGE_ACTION ]
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete all selected sessions, prompting the user first to confirm that
|
||||
* deletion is desired.
|
||||
*/
|
||||
$scope.deleteSessions = function deleteSessions() {
|
||||
// Confirm deletion request
|
||||
guacNotification.showStatus({
|
||||
'title' : 'MANAGE_SESSION.DIALOG_HEADER_CONFIRM_DELETE',
|
||||
'text' : 'MANAGE_SESSION.TEXT_CONFIRM_DELETE',
|
||||
'actions' : [ DELETE_ACTION, CANCEL_ACTION]
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether the selected sessions can be deleted.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
* true if selected sessions can be deleted, false otherwise.
|
||||
*/
|
||||
$scope.canDeleteSessions = function canDeleteSessions() {
|
||||
|
||||
// We can delete sessions if at least one is selected
|
||||
for (var identifier in selectedWrappers)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Called whenever an active connection wrapper changes selected status.
|
||||
*
|
||||
* @param {ActiveConnectionWrapper} wrapper
|
||||
* The wrapper whose selected status has changed.
|
||||
*/
|
||||
$scope.wrapperSelectionChange = function wrapperSelectionChange(wrapper) {
|
||||
|
||||
// Add wrapper to map if selected
|
||||
if (wrapper.checked)
|
||||
selectedWrappers[wrapper.activeConnection.identifier] = wrapper;
|
||||
|
||||
// Otherwise, remove wrapper from map
|
||||
else
|
||||
delete selectedWrappers[wrapper.activeConnection.identifier];
|
||||
|
||||
};
|
||||
|
||||
}]
|
||||
};
|
||||
|
||||
}]);
|
@@ -20,15 +20,15 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
.manage table.session-list {
|
||||
.settings table.session-list {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.manage table.session-list tr.session:hover {
|
||||
.settings table.session-list tr.session:hover {
|
||||
background: #CDA;
|
||||
}
|
||||
|
||||
.manage table.session-list .select-session {
|
||||
.settings table.session-list .select-session {
|
||||
min-width: 2em;
|
||||
text-align: center;
|
||||
}
|
@@ -24,6 +24,17 @@
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.settings table.properties th {
|
||||
text-align: left;
|
||||
font-weight: normal;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
.settings .action-buttons {
|
||||
text-align: center;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.settings-tabs .page-list {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
@@ -0,0 +1,77 @@
|
||||
<div class="settings section sessions" ng-class="{loading: !isLoaded()}">
|
||||
<!--
|
||||
Copyright 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.
|
||||
-->
|
||||
|
||||
<!-- User Session management -->
|
||||
<p>{{'MANAGE_SESSION.HELP_SESSIONS' | translate}}</p>
|
||||
|
||||
<!-- Form action buttons -->
|
||||
<div class="action-buttons">
|
||||
<button class="delete-sessions danger" ng-disabled="!canDeleteSessions()" ng-click="deleteSessions()">{{'MANAGE_SESSION.ACTION_DELETE' | translate}}</button>
|
||||
</div>
|
||||
|
||||
<!-- Session filter -->
|
||||
<guac-filter filtered-items="filteredWrappers" items="wrappers"
|
||||
placeholder="'MANAGE_SESSION.FIELD_PLACEHOLDER_FILTER' | translate"
|
||||
properties="filteredWrapperProperties"></guac-filter>
|
||||
|
||||
<!-- List of current user sessions -->
|
||||
<table class="sorted session-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="select-session"></th>
|
||||
<th guac-sort-order="wrapperOrder" guac-sort-property="'activeConnection.username'">
|
||||
{{'MANAGE_SESSION.TABLE_HEADER_SESSION_USERNAME' | translate}}
|
||||
</th>
|
||||
<th guac-sort-order="wrapperOrder" guac-sort-property="'startDate'">
|
||||
{{'MANAGE_SESSION.TABLE_HEADER_SESSION_STARTDATE' | translate}}
|
||||
</th>
|
||||
<th guac-sort-order="wrapperOrder" guac-sort-property="'activeConnection.remoteHost'">
|
||||
{{'MANAGE_SESSION.TABLE_HEADER_SESSION_REMOTEHOST' | translate}}
|
||||
</th>
|
||||
<th guac-sort-order="wrapperOrder" guac-sort-property="'name'">
|
||||
{{'MANAGE_SESSION.TABLE_HEADER_SESSION_CONNECTION_NAME' | translate}}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="wrapper in wrapperPage" class="session">
|
||||
<td class="select-session">
|
||||
<input ng-change="wrapperSelectionChange(wrapper)" type="checkbox" ng-model="wrapper.checked" />
|
||||
</td>
|
||||
<td>{{wrapper.activeConnection.username}}</td>
|
||||
<td>{{wrapper.startDate}}</td>
|
||||
<td>{{wrapper.activeConnection.remoteHost}}</td>
|
||||
<td>{{wrapper.name}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- Text displayed if no sessions exist -->
|
||||
<p class="placeholder" ng-hide="wrapperPage.length">
|
||||
{{'MANAGE_SESSION.INFO_NO_SESSIONS' | translate}}
|
||||
</p>
|
||||
|
||||
<!-- Pager for session list -->
|
||||
<guac-pager page="wrapperPage" page-size="25"
|
||||
items="filteredWrappers | orderBy : wrapperOrder.predicate"></guac-pager>
|
||||
</div>
|
@@ -35,5 +35,6 @@ THE SOFTWARE.
|
||||
<!-- Selected tab -->
|
||||
<guac-manage-users ng-if="activeTab === 'users'"></guac-manage-users>
|
||||
<guac-manage-connections ng-if="activeTab === 'connections'"></guac-manage-connections>
|
||||
<guac-manage-sessions ng-if="activeTab === 'sessions'"></guac-manage-sessions>
|
||||
|
||||
</div>
|
||||
|
@@ -23,7 +23,7 @@
|
||||
/**
|
||||
* A service for defining the ActiveConnectionWrapper class.
|
||||
*/
|
||||
angular.module('manage').factory('ActiveConnectionWrapper', [
|
||||
angular.module('settings').factory('ActiveConnectionWrapper', [
|
||||
function defineActiveConnectionWrapper() {
|
||||
|
||||
/**
|
Reference in New Issue
Block a user