GUACAMOLE-1866: Add capability for users to configure recent connections.

This commit is contained in:
Virtually Nick
2023-10-12 22:50:17 -04:00
parent d03da4a385
commit 4ab265af73
11 changed files with 86 additions and 24 deletions

View File

@@ -28,18 +28,13 @@ angular.module('history').factory('guacHistory', ['$injector',
// Required services // Required services
var localStorageService = $injector.get('localStorageService'); var localStorageService = $injector.get('localStorageService');
var preferenceService = $injector.get('preferenceService');
var service = {}; var service = {};
// The parameter name for getting the history from local storage // The parameter name for getting the history from local storage
var GUAC_HISTORY_STORAGE_KEY = "GUAC_HISTORY"; var GUAC_HISTORY_STORAGE_KEY = "GUAC_HISTORY";
/**
* The number of entries to allow before removing old entries based on the
* cutoff.
*/
var IDEAL_LENGTH = 6;
/** /**
* The top few recent connections, sorted in order of most recent access. * The top few recent connections, sorted in order of most recent access.
* *
@@ -77,8 +72,8 @@ angular.module('history').factory('guacHistory', ['$injector',
)); ));
// Truncate history to ideal length // Truncate history to ideal length
if (service.recentConnections.length > IDEAL_LENGTH) if (service.recentConnections.length > preferenceService.preferences.numberOfRecentConnections)
service.recentConnections.length = IDEAL_LENGTH; service.recentConnections.length = preferenceService.preferences.numberOfRecentConnections;
// Save updated history // Save updated history
localStorageService.setItem(GUAC_HISTORY_STORAGE_KEY, service.recentConnections); localStorageService.setItem(GUAC_HISTORY_STORAGE_KEY, service.recentConnections);

View File

@@ -31,6 +31,7 @@ angular.module('home').controller('homeController', ['$scope', '$injector',
var authenticationService = $injector.get('authenticationService'); var authenticationService = $injector.get('authenticationService');
var connectionGroupService = $injector.get('connectionGroupService'); var connectionGroupService = $injector.get('connectionGroupService');
var dataSourceService = $injector.get('dataSourceService'); var dataSourceService = $injector.get('dataSourceService');
var preferenceService = $injector.get('preferenceService');
var requestService = $injector.get('requestService'); var requestService = $injector.get('requestService');
/** /**
@@ -60,6 +61,16 @@ angular.module('home').controller('homeController', ['$scope', '$injector',
'name' 'name'
]; ];
/**
* Returns true if recent connections should be displayed on the Guacamole
* home page, otherwise false.
*
* @returns {!boolean}
*/
$scope.willShowRecentConnections = function willShowRecentConnections() {
return preferenceService.preferences.showRecentConnections;
};
/** /**
* Returns whether critical data has completed being loaded. * Returns whether critical data has completed being loaded.
* *

View File

@@ -50,6 +50,7 @@ angular.module('home').directive('guacRecentConnections', [function guacRecentCo
// Required services // Required services
var guacHistory = $injector.get('guacHistory'); var guacHistory = $injector.get('guacHistory');
var preferenceService = $injector.get('preferenceService');
/** /**
* Array of all known and visible recently-used connections. * Array of all known and visible recently-used connections.
@@ -58,10 +59,20 @@ angular.module('home').directive('guacRecentConnections', [function guacRecentCo
*/ */
$scope.recentConnections = []; $scope.recentConnections = [];
/**
* Returns whether or not recent connections should be displayed.
*
* @returns {!boolean}
* true if recent connections should be displayed, otherwise false.
*/
$scope.willShowRecentConnections = function willShowRecentConnections() {
return preferenceService.preferences.showRecentConnections;
};
/** /**
* Returns whether recent connections are available for display. * Returns whether recent connections are available for display.
* *
* @returns {Boolean} * @returns {!boolean}
* true if recent connections are present, false otherwise. * true if recent connections are present, false otherwise.
*/ */
$scope.hasRecentConnections = function hasRecentConnections() { $scope.hasRecentConnections = function hasRecentConnections() {

View File

@@ -75,3 +75,8 @@ a.home-connection, .empty.balancer a.home-connection-group {
.all-connections .connection-group.empty.balancer > .caption .icon.expand { .all-connections .connection-group.empty.balancer > .caption .icon.expand {
display: none; display: none;
} }
.header-app-name {
font-size: 0.85em;
box-shadow: none;
}

View File

@@ -1,4 +1,4 @@
<div class="recent-connections"> <div class="recent-connections" ng-show="willShowRecentConnections()">
<!-- Text displayed if no recent connections exist --> <!-- Text displayed if no recent connections exist -->
<p class="placeholder" ng-hide="hasRecentConnections()">{{'HOME.INFO_NO_RECENT_CONNECTIONS' | translate}}</p> <p class="placeholder" ng-hide="hasRecentConnections()">{{'HOME.INFO_NO_RECENT_CONNECTIONS' | translate}}</p>

View File

@@ -2,12 +2,16 @@
<div class="connection-list-ui"> <div class="connection-list-ui">
<!-- The recent connections for this user --> <div class="header header-app-name">
<div class="header"> <h2 id="section-header-app-name">{{'APP.NAME' | translate}}</h2>
<h2 id="section-header-recent-connections">{{'HOME.SECTION_HEADER_RECENT_CONNECTIONS' | translate}}</h2>
<guac-user-menu></guac-user-menu> <guac-user-menu></guac-user-menu>
</div> </div>
<guac-recent-connections root-groups="rootConnectionGroups"></guac-recent-connections>
<!-- The recent connections for this user -->
<div class="header" ng-show="willShowRecentConnections()">
<h2 id="section-header-recent-connections">{{'HOME.SECTION_HEADER_RECENT_CONNECTIONS' | translate}}</h2>
</div>
<guac-recent-connections root-groups="rootConnectionGroups" ng-show="willShowRecentConnections()"></guac-recent-connections>
<!-- All connections for this user --> <!-- All connections for this user -->
<div class="header"> <div class="header">

View File

@@ -42,7 +42,7 @@ h2 {
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.125); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.125);
background: rgba(0, 0, 0, 0.04); background: rgba(0, 0, 0, 0.04);
margin-bottom: 1em; margin-bottom: 0;
margin-top: 0; margin-top: 0;
border-top: none; border-top: none;
width: 100%; width: 100%;
@@ -80,7 +80,7 @@ h2 {
.header ~ * .header, .header ~ * .header,
.header ~ .header { .header ~ .header {
margin-top: 1em; margin-top: 0;
border-top: 1px solid rgba(0, 0, 0, 0.125); border-top: 1px solid rgba(0, 0, 0, 0.125);
} }

View File

@@ -258,7 +258,7 @@ angular.module('settings').directive('guacSettingsPreferences', [function guacSe
// Fetch the user record // Fetch the user record
userService.getUser(dataSource, username).then(function saveUserData(user) { userService.getUser(dataSource, username).then(function saveUserData(user) {
$scope.user = user; $scope.user = user;
}) });
// Fetch all user preference attribute forms defined // Fetch all user preference attribute forms defined
schemaService.getUserPreferenceAttributes(dataSource).then(function saveAttributes(attributes) { schemaService.getUserPreferenceAttributes(dataSource).then(function saveAttributes(attributes) {

View File

@@ -142,6 +142,20 @@ angular.module('settings').provider('preferenceService', ['$injector',
*/ */
language : getDefaultLanguageKey(), language : getDefaultLanguageKey(),
/**
* The number of recent connections to display.
*
* @type {!number}
*/
numberOfRecentConnections: 6,
/**
* Whether or not to show the "Recent Connections" section.
*
* @type {!boolean}
*/
showRecentConnections : true,
/** /**
* The timezone set by the user, in IANA zone key format (Olson time * The timezone set by the user, in IANA zone key format (Olson time
* zone database). * zone database).

View File

@@ -89,6 +89,24 @@
</div> </div>
</div> </div>
<!-- Recent connections -->
<h2 class="header">{{'SETTINGS_PREFERENCES.SECTION_HEADER_RECENT_CONNECTIONS' | translate}}</h2>
<div class="settings section recent">
<p>{{'SETTINGS_PREFERENCES.HELP_RECENT_CONNECTIONS' | translate}}</p>
<div class='form'>
<table class='fields'>
<tr>
<th>{{'SETTINGS_PREFERENCES.FIELD_HEADER_SHOW_RECENT_CONNECTIONS' | translate}}</th>
<td><input ng-model="preferences.showRecentConnections" type="checkbox"/></td>
</tr>
<tr>
<th>{{'SETTINGS_PREFERENCES.FIELD_HEADER_NUMBER_RECENT_CONNECTIONS' | translate}}</th>
<td><input ng-model="preferences.numberOfRecentConnections" type="number" min="1" max="20"/></td>
</tr>
</table>
</div>
</div>
<!-- User attributes section --> <!-- User attributes section -->
<div class="attributes" ng-show="canUpdateSelf && attributes.length"> <div class="attributes" ng-show="canUpdateSelf && attributes.length">
<guac-form namespace="'USER_ATTRIBUTES'" content="attributes" <guac-form namespace="'USER_ATTRIBUTES'" content="attributes"

View File

@@ -1023,13 +1023,15 @@
"ERROR_PASSWORD_BLANK" : "@:APP.ERROR_PASSWORD_BLANK", "ERROR_PASSWORD_BLANK" : "@:APP.ERROR_PASSWORD_BLANK",
"ERROR_PASSWORD_MISMATCH" : "@:APP.ERROR_PASSWORD_MISMATCH", "ERROR_PASSWORD_MISMATCH" : "@:APP.ERROR_PASSWORD_MISMATCH",
"FIELD_HEADER_LANGUAGE" : "Display language:", "FIELD_HEADER_LANGUAGE" : "Display language:",
"FIELD_HEADER_PASSWORD" : "Password:", "FIELD_HEADER_NUMBER_RECENT_CONNECTIONS" : "Number of Recent Connections to show:",
"FIELD_HEADER_PASSWORD_OLD" : "Current Password:", "FIELD_HEADER_PASSWORD" : "Password:",
"FIELD_HEADER_PASSWORD_NEW" : "New Password:", "FIELD_HEADER_PASSWORD_OLD" : "Current Password:",
"FIELD_HEADER_PASSWORD_NEW_AGAIN" : "Confirm New Password:", "FIELD_HEADER_PASSWORD_NEW" : "New Password:",
"FIELD_HEADER_TIMEZONE" : "Timezone:", "FIELD_HEADER_PASSWORD_NEW_AGAIN" : "Confirm New Password:",
"FIELD_HEADER_USERNAME" : "Username:", "FIELD_HEADER_SHOW_RECENT_CONNECTIONS" : "Display Recent Connections:",
"FIELD_HEADER_TIMEZONE" : "Timezone:",
"FIELD_HEADER_USERNAME" : "Username:",
"HELP_DEFAULT_INPUT_METHOD" : "The default input method determines how keyboard events are received by Guacamole. Changing this setting may be necessary when using a mobile device, or when typing through an IME. This setting can be overridden on a per-connection basis within the Guacamole menu.", "HELP_DEFAULT_INPUT_METHOD" : "The default input method determines how keyboard events are received by Guacamole. Changing this setting may be necessary when using a mobile device, or when typing through an IME. This setting can be overridden on a per-connection basis within the Guacamole menu.",
"HELP_DEFAULT_MOUSE_MODE" : "The default mouse emulation mode determines how the remote mouse will behave in new connections with respect to touches. This setting can be overridden on a per-connection basis within the Guacamole menu.", "HELP_DEFAULT_MOUSE_MODE" : "The default mouse emulation mode determines how the remote mouse will behave in new connections with respect to touches. This setting can be overridden on a per-connection basis within the Guacamole menu.",
@@ -1039,6 +1041,7 @@
"HELP_LOCALE" : "Options below are related to the locale of the user and will impact how various parts of the interface are displayed.", "HELP_LOCALE" : "Options below are related to the locale of the user and will impact how various parts of the interface are displayed.",
"HELP_MOUSE_MODE_ABSOLUTE" : "@:CLIENT.HELP_MOUSE_MODE_ABSOLUTE", "HELP_MOUSE_MODE_ABSOLUTE" : "@:CLIENT.HELP_MOUSE_MODE_ABSOLUTE",
"HELP_MOUSE_MODE_RELATIVE" : "@:CLIENT.HELP_MOUSE_MODE_RELATIVE", "HELP_MOUSE_MODE_RELATIVE" : "@:CLIENT.HELP_MOUSE_MODE_RELATIVE",
"HELP_RECENT_CONNECTIONS" : "Here you can enable or disable recent conections in the Guacamole Home Page, and adjust the number of recent connections that will be displayed.",
"HELP_UPDATE_PASSWORD" : "If you wish to change your password, enter your current password and the desired new password below, and click \"Update Password\". The change will take effect immediately.", "HELP_UPDATE_PASSWORD" : "If you wish to change your password, enter your current password and the desired new password below, and click \"Update Password\". The change will take effect immediately.",
"INFO_PASSWORD_CHANGED" : "Password changed.", "INFO_PASSWORD_CHANGED" : "Password changed.",
@@ -1050,6 +1053,7 @@
"SECTION_HEADER_DEFAULT_INPUT_METHOD" : "Default Input Method", "SECTION_HEADER_DEFAULT_INPUT_METHOD" : "Default Input Method",
"SECTION_HEADER_DEFAULT_MOUSE_MODE" : "Default Mouse Emulation Mode", "SECTION_HEADER_DEFAULT_MOUSE_MODE" : "Default Mouse Emulation Mode",
"SECTION_HEADER_RECENT_CONNECTIONS" : "Recent Connections Preferences",
"SECTION_HEADER_UPDATE_PASSWORD" : "Change Password" "SECTION_HEADER_UPDATE_PASSWORD" : "Change Password"
}, },