From 2d0bc70214cd3de7b06bcf188cd21f8f6abe708a Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 12 Nov 2018 09:40:32 -0800 Subject: [PATCH 01/17] GUACAMOLE-723: Avoid DOM reflow when switching connections. --- .../webapp/app/client/styles/keyboard.css | 7 +++++ .../webapp/app/client/styles/text-input.css | 26 +++++++++++++++++++ .../webapp/app/client/templates/client.html | 4 +-- 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 guacamole/src/main/webapp/app/client/styles/text-input.css diff --git a/guacamole/src/main/webapp/app/client/styles/keyboard.css b/guacamole/src/main/webapp/app/client/styles/keyboard.css index 8076d5480..e5bb96317 100644 --- a/guacamole/src/main/webapp/app/client/styles/keyboard.css +++ b/guacamole/src/main/webapp/app/client/styles/keyboard.css @@ -18,6 +18,8 @@ */ .keyboard-container { + + display: none; text-align: center; width: 100%; @@ -29,4 +31,9 @@ opacity: 0.85; z-index: 1; + } + +.keyboard-container.open { + display: block; +} \ No newline at end of file diff --git a/guacamole/src/main/webapp/app/client/styles/text-input.css b/guacamole/src/main/webapp/app/client/styles/text-input.css new file mode 100644 index 000000000..28e905ef4 --- /dev/null +++ b/guacamole/src/main/webapp/app/client/styles/text-input.css @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +.text-input-container { + display: none; +} + +.text-input-container.open { + display: block; +} diff --git a/guacamole/src/main/webapp/app/client/templates/client.html b/guacamole/src/main/webapp/app/client/templates/client.html index ad85f234e..93dc417ce 100644 --- a/guacamole/src/main/webapp/app/client/templates/client.html +++ b/guacamole/src/main/webapp/app/client/templates/client.html @@ -17,12 +17,12 @@
-
+
-
+
From f92bf9c35ffe28cccdc3cc80cdc70336975f4b80 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 12 Nov 2018 10:08:36 -0800 Subject: [PATCH 02/17] GUACAMOLE-723: Move getClientIdentifier() to GroupListItem for convenience of other uses of the guacGroupList directive. --- .../webapp/app/groupList/groupListModule.js | 6 ++- .../app/groupList/types/GroupListItem.js | 46 +++++++++++++++++-- .../app/home/controllers/homeController.js | 46 ------------------- .../webapp/app/home/templates/connection.html | 2 +- .../app/home/templates/connectionGroup.html | 2 +- .../main/webapp/app/home/templates/home.html | 1 - 6 files changed, 50 insertions(+), 53 deletions(-) diff --git a/guacamole/src/main/webapp/app/groupList/groupListModule.js b/guacamole/src/main/webapp/app/groupList/groupListModule.js index 14f470651..eb37ac5c7 100644 --- a/guacamole/src/main/webapp/app/groupList/groupListModule.js +++ b/guacamole/src/main/webapp/app/groupList/groupListModule.js @@ -21,4 +21,8 @@ * Module for displaying the contents of a connection group, allowing the user * to select individual connections or groups. */ -angular.module('groupList', ['list', 'rest']); +angular.module('groupList', [ + 'navigation', + 'list', + 'rest' +]); diff --git a/guacamole/src/main/webapp/app/groupList/types/GroupListItem.js b/guacamole/src/main/webapp/app/groupList/types/GroupListItem.js index e6629728d..29bf91bd3 100644 --- a/guacamole/src/main/webapp/app/groupList/types/GroupListItem.js +++ b/guacamole/src/main/webapp/app/groupList/types/GroupListItem.js @@ -20,7 +20,11 @@ /** * Provides the GroupListItem class definition. */ -angular.module('groupList').factory('GroupListItem', ['ConnectionGroup', function defineGroupListItem(ConnectionGroup) { +angular.module('groupList').factory('GroupListItem', ['$injector', function defineGroupListItem($injector) { + + // Required types + var ClientIdentifier = $injector.get('ClientIdentifier'); + var ConnectionGroup = $injector.get('ConnectionGroup'); /** * Creates a new GroupListItem, initializing the properties of that @@ -109,14 +113,50 @@ angular.module('groupList').factory('GroupListItem', ['ConnectionGroup', functio /** * Returns the number of currently active users for this connection, - * connection group, or sharing profile, if known. + * connection group, or sharing profile, if known. If unknown, null may + * be returned. * - * @type Number + * @returns {Number} + * The number of currently active users for this connection, + * connection group, or sharing profile. */ this.getActiveConnections = template.getActiveConnections || (function getActiveConnections() { return null; }); + /** + * Returns the unique string identifier that must be used when + * connecting to a connection or connection group represented by this + * GroupListItem. + * + * @returns {String} + * The client identifier associated with the connection or + * connection group represented by this GroupListItem, or null if + * this GroupListItem cannot have an associated client identifier. + */ + this.getClientIdentifier = template.getClientIdentifier || function getClientIdentifier() { + + // If the item is a connection, generate a connection identifier + if (this.type === GroupListItem.Type.CONNECTION) + return ClientIdentifier.toString({ + dataSource : this.dataSource, + type : ClientIdentifier.Types.CONNECTION, + id : this.identifier + }); + + // If the item is a connection group, generate a connection group identifier + if (this.type === GroupListItem.Type.CONNECTION_GROUP) + return ClientIdentifier.toString({ + dataSource : this.dataSource, + type : ClientIdentifier.Types.CONNECTION_GROUP, + id : this.identifier + }); + + // Otherwise, no such identifier can exist + return null; + + }; + /** * The connection, connection group, or sharing profile whose data is * exposed within this GroupListItem. If the type of this GroupListItem diff --git a/guacamole/src/main/webapp/app/home/controllers/homeController.js b/guacamole/src/main/webapp/app/home/controllers/homeController.js index 6c2bd6922..a6d359e7f 100644 --- a/guacamole/src/main/webapp/app/home/controllers/homeController.js +++ b/guacamole/src/main/webapp/app/home/controllers/homeController.js @@ -25,7 +25,6 @@ angular.module('home').controller('homeController', ['$scope', '$injector', // Get required types var ConnectionGroup = $injector.get('ConnectionGroup'); - var ClientIdentifier = $injector.get('ClientIdentifier'); var GroupListItem = $injector.get('GroupListItem'); // Get required services @@ -74,51 +73,6 @@ angular.module('home').controller('homeController', ['$scope', '$injector', }; - /** - * Object passed to the guacGroupList directive, providing context-specific - * functions or data. - */ - $scope.context = { - - /** - * Returns the unique string identifier which must be used when - * connecting to a connection or connection group represented by the - * given GroupListItem. - * - * @param {GroupListItem} item - * The GroupListItem to determine the client identifier of. - * - * @returns {String} - * The client identifier associated with the connection or - * connection group represented by the given GroupListItem, or null - * if the GroupListItem cannot have an associated client - * identifier. - */ - getClientIdentifier : function getClientIdentifier(item) { - - // If the item is a connection, generate a connection identifier - if (item.type === GroupListItem.Type.CONNECTION) - return ClientIdentifier.toString({ - dataSource : item.dataSource, - type : ClientIdentifier.Types.CONNECTION, - id : item.identifier - }); - - // If the item is a connection group, generate a connection group identifier - if (item.type === GroupListItem.Type.CONNECTION_GROUP) - return ClientIdentifier.toString({ - dataSource : item.dataSource, - type : ClientIdentifier.Types.CONNECTION_GROUP, - id : item.identifier - }); - - // Otherwise, no such identifier can exist - return null; - - } - - }; - // Retrieve root groups and all descendants dataSourceService.apply( connectionGroupService.getConnectionGroupTree, diff --git a/guacamole/src/main/webapp/app/home/templates/connection.html b/guacamole/src/main/webapp/app/home/templates/connection.html index 3f244fb3e..b4284126a 100644 --- a/guacamole/src/main/webapp/app/home/templates/connection.html +++ b/guacamole/src/main/webapp/app/home/templates/connection.html @@ -1,5 +1,5 @@ diff --git a/guacamole/src/main/webapp/app/home/templates/connectionGroup.html b/guacamole/src/main/webapp/app/home/templates/connectionGroup.html index f1261dca1..6b5426457 100644 --- a/guacamole/src/main/webapp/app/home/templates/connectionGroup.html +++ b/guacamole/src/main/webapp/app/home/templates/connectionGroup.html @@ -1,4 +1,4 @@ - {{item.name}} + {{item.name}} {{item.name}} diff --git a/guacamole/src/main/webapp/app/home/templates/home.html b/guacamole/src/main/webapp/app/home/templates/home.html index f68a0a9f9..4597dffe1 100644 --- a/guacamole/src/main/webapp/app/home/templates/home.html +++ b/guacamole/src/main/webapp/app/home/templates/home.html @@ -23,7 +23,6 @@
-

{{client.name}}

+

{{client.name}}

+

+ +
+ +
+
+

diff --git a/guacamole/src/main/webapp/app/client/templates/guacClientPanel.html b/guacamole/src/main/webapp/app/client/templates/guacClientPanel.html new file mode 100644 index 000000000..67fcfcf01 --- /dev/null +++ b/guacamole/src/main/webapp/app/client/templates/guacClientPanel.html @@ -0,0 +1,13 @@ + \ No newline at end of file diff --git a/guacamole/src/main/webapp/images/arrows/left.png b/guacamole/src/main/webapp/images/arrows/left.png new file mode 100644 index 0000000000000000000000000000000000000000..920a4fd76a224447bb5197bb46a426599b532695 GIT binary patch literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=Y)RhkE)4%caKYZ?lYt_f1s;*b zKpodXn9)gNb_Gz7y~NYkmHjcZxR`;3Wo!FYpir}?i(^Q|t+zK0@*Xk}VLjNf%+l$3 zzmk*Ek#i**!gA`LTL2X?)SX@}x4-JotB@4}1VVj%zk literal 0 HcmV?d00001 From e0dcd67a9ba8ee2e43bba348b2456745c54b2ebf Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 23 Mar 2019 16:17:37 -0700 Subject: [PATCH 06/17] GUACAMOLE-723: Update size of attached client when a different client is attached. --- guacamole/src/main/webapp/app/client/directives/guacClient.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/guacamole/src/main/webapp/app/client/directives/guacClient.js b/guacamole/src/main/webapp/app/client/directives/guacClient.js index 769edd703..cc8829657 100644 --- a/guacamole/src/main/webapp/app/client/directives/guacClient.js +++ b/guacamole/src/main/webapp/app/client/directives/guacClient.js @@ -282,6 +282,9 @@ angular.module('client').directive('guacClient', [function guacClient() { return false; }; + // Size of newly-attached client may be different + $scope.mainElementResized(); + }); // Update actual view scrollLeft when scroll properties change From 53bb1981c1d53d4bc1eee6db8e0584cc3586a1bb Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 23 Mar 2019 16:57:19 -0700 Subject: [PATCH 07/17] GUACAMOLE-723: Persist client panel state across navigation. --- .../app/client/directives/guacClientPanel.js | 40 ++++++++++++++----- .../app/client/styles/other-connections.css | 5 +++ .../app/client/templates/guacClientPanel.html | 8 +++- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/guacamole/src/main/webapp/app/client/directives/guacClientPanel.js b/guacamole/src/main/webapp/app/client/directives/guacClientPanel.js index bca1498cc..737fce9c4 100644 --- a/guacamole/src/main/webapp/app/client/directives/guacClientPanel.js +++ b/guacamole/src/main/webapp/app/client/directives/guacClientPanel.js @@ -22,7 +22,20 @@ * panel is fixed to the bottom-right corner of its container and can be * manually hidden/exposed by the user. */ -angular.module('client').directive('guacClientPanel', [function guacClientPanel() { +angular.module('client').directive('guacClientPanel', ['$injector', function guacClientPanel($injector) { + + var sessionStorageFactory = $injector.get('sessionStorageFactory'); + + /** + * Getter/setter for the boolean flag controlling whether the client panel + * is currently hidden. This flag is maintained in session-local storage to + * allow the state of the panel to persist despite navigation within the + * same tab. When hidden, the panel will be collapsed against the right + * side of the container. By default, the panel is visible. + * + * @type Function + */ + var panelHidden = sessionStorageFactory.create(false); return { // Element only @@ -34,7 +47,7 @@ angular.module('client').directive('guacClientPanel', [function guacClientPanel( * The ManagedClient instances associated with the active * connections to be displayed within this panel. * - * @type ManagedClient[] + * @type ManagedClient[]|Object. */ clients : '=' @@ -51,19 +64,28 @@ angular.module('client').directive('guacClientPanel', [function guacClientPanel( var scrollableArea = $element.find('.client-panel-connection-list')[0]; /** - * Whether the client panel is currently hidden. When hidden, the - * panel will be collapsed against the right side of the - * containiner. - * - * @type Boolean + * On-scope reference to session-local storage of the flag + * controlling whether then panel is hidden. */ - $scope.panelHidden = false; + $scope.panelHidden = panelHidden; + + /** + * Returns whether this panel currently has any clients associated + * with it. + * + * @return {Boolean} + * true if at least one client is associated with this panel, + * false otherwise. + */ + $scope.hasClients = function hasClients() { + return !_.isEmpty($scope.clients); + }; /** * Toggles whether the client panel is currently hidden. */ $scope.togglePanel = function togglePanel() { - $scope.panelHidden = !$scope.panelHidden; + panelHidden(!panelHidden()); }; // Override vertical scrolling, scrolling horizontally instead diff --git a/guacamole/src/main/webapp/app/client/styles/other-connections.css b/guacamole/src/main/webapp/app/client/styles/other-connections.css index 26da0a783..b106ec218 100644 --- a/guacamole/src/main/webapp/app/client/styles/other-connections.css +++ b/guacamole/src/main/webapp/app/client/styles/other-connections.css @@ -26,6 +26,7 @@ #other-connections .client-panel { + display: none; position: absolute; right: 0; bottom: 0; @@ -38,6 +39,10 @@ } +#other-connections .client-panel.has-clients { + display: block; +} + #other-connections .client-panel.hidden { max-width: 16px; } diff --git a/guacamole/src/main/webapp/app/client/templates/guacClientPanel.html b/guacamole/src/main/webapp/app/client/templates/guacClientPanel.html index 67fcfcf01..e550c849f 100644 --- a/guacamole/src/main/webapp/app/client/templates/guacClientPanel.html +++ b/guacamole/src/main/webapp/app/client/templates/guacClientPanel.html @@ -1,5 +1,10 @@ -
+ \ No newline at end of file From 07a967bb6b8b735c666b5c760c487f3abc4880f2 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 23 Mar 2019 16:57:56 -0700 Subject: [PATCH 08/17] GUACAMOLE-723: Ensure client panel renders above status notifications. --- .../webapp/app/client/styles/other-connections.css | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/guacamole/src/main/webapp/app/client/styles/other-connections.css b/guacamole/src/main/webapp/app/client/styles/other-connections.css index b106ec218..0570c23e0 100644 --- a/guacamole/src/main/webapp/app/client/styles/other-connections.css +++ b/guacamole/src/main/webapp/app/client/styles/other-connections.css @@ -17,13 +17,6 @@ * under the License. */ -#other-connections { - - /* Render above modal status */ - z-index: 20; - -} - #other-connections .client-panel { display: none; @@ -37,6 +30,9 @@ white-space: nowrap; transition: max-width 0.125s, width 0.125s; + /* Render above modal status */ + z-index: 20; + } #other-connections .client-panel.has-clients { From dc012e4226a5a561473499d5a28575313d709053 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 25 Mar 2019 17:00:56 -0700 Subject: [PATCH 09/17] GUACAMOLE-723: Hide scrollbar and thumbnails when client panel is hidden. --- .../webapp/app/client/styles/other-connections.css | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/guacamole/src/main/webapp/app/client/styles/other-connections.css b/guacamole/src/main/webapp/app/client/styles/other-connections.css index 0570c23e0..41069ded4 100644 --- a/guacamole/src/main/webapp/app/client/styles/other-connections.css +++ b/guacamole/src/main/webapp/app/client/styles/other-connections.css @@ -100,6 +100,18 @@ } +#other-connections .client-panel.hidden .client-panel-connection-list { + /* Hide scrollbar when panel is hidden (will be visible through panel + * show/hide button otherwise) */ + overflow-x: hidden; +} + +#other-connections .client-panel.hidden .client-panel-connection { + /* Hide thumbnails when panel is hidden (will be visible through panel + * show/hide button otherwise) */ + visibility: hidden; +} + #other-connections .client-panel-connection .name { position: absolute; From bd474e9761d67e89314c640412872f5c501caa09 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 2 Apr 2019 07:47:40 -0700 Subject: [PATCH 10/17] GUACAMOLE-723: Allow mouse interaction with the contents of a menu without closing the menu. --- .../webapp/app/navigation/directives/guacMenu.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/guacamole/src/main/webapp/app/navigation/directives/guacMenu.js b/guacamole/src/main/webapp/app/navigation/directives/guacMenu.js index e00cc1c4f..92e2c6c6d 100644 --- a/guacamole/src/main/webapp/app/navigation/directives/guacMenu.js +++ b/guacamole/src/main/webapp/app/navigation/directives/guacMenu.js @@ -52,6 +52,14 @@ angular.module('navigation').directive('guacMenu', [function guacMenu() { */ var element = $element[0]; + /** + * The element containing the menu contents that display when the + * menu is open. + * + * @type Element + */ + var contents = $element.find('.menu-contents')[0]; + /** * The main document object. * @@ -85,6 +93,11 @@ angular.module('navigation').directive('guacMenu', [function guacMenu() { e.stopPropagation(); }, false); + // Prevent click within menu contents from toggling menu visibility + contents.addEventListener('click', function clickInsideMenuContents(e) { + e.stopPropagation(); + }, false); + }] // end controller }; From 7fddb26202ab298f53a21e9c757bace9bddd1232 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 2 Apr 2019 07:48:57 -0700 Subject: [PATCH 11/17] GUACAMOLE-723: Limit size of connections in menu to 10 items. Restore padding around list and pager. --- guacamole/src/main/webapp/app/client/styles/guac-menu.css | 5 ----- guacamole/src/main/webapp/app/client/templates/client.html | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/guacamole/src/main/webapp/app/client/styles/guac-menu.css b/guacamole/src/main/webapp/app/client/styles/guac-menu.css index e3bc708ab..73562ceb8 100644 --- a/guacamole/src/main/webapp/app/client/styles/guac-menu.css +++ b/guacamole/src/main/webapp/app/client/styles/guac-menu.css @@ -71,7 +71,6 @@ #guac-menu .header h2 .menu-dropdown { border: none; - background: transparent; } #guac-menu .header h2 .menu-contents { @@ -79,10 +78,6 @@ font-size: 0.8em; } -#guac-menu .header h2 .menu-contents .all-connections { - margin: 0; -} - #guac-menu #mouse-settings .choice { text-align: center; } diff --git a/guacamole/src/main/webapp/app/client/templates/client.html b/guacamole/src/main/webapp/app/client/templates/client.html index 01159b7ea..6e40461e4 100644 --- a/guacamole/src/main/webapp/app/client/templates/client.html +++ b/guacamole/src/main/webapp/app/client/templates/client.html @@ -62,7 +62,7 @@ 'connection' : 'app/client/templates/connection.html', 'connection-group' : 'app/client/templates/connectionGroup.html' }" - page-size="20"> + page-size="10">
From 19da6e32a2b7cc87750a07d16e881999f76ba9dd Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 2 Apr 2019 08:44:45 -0700 Subject: [PATCH 12/17] GUACAMOLE-723: Allow connections in Guacamole menu dropdown to be filtered. --- .../app/client/controllers/clientController.js | 18 ++++++++++++++++++ .../webapp/app/client/styles/guac-menu.css | 10 ++++++++++ .../webapp/app/client/templates/client.html | 7 ++++++- guacamole/src/main/webapp/translations/de.json | 2 ++ guacamole/src/main/webapp/translations/en.json | 2 ++ guacamole/src/main/webapp/translations/es.json | 2 ++ guacamole/src/main/webapp/translations/fr.json | 2 ++ guacamole/src/main/webapp/translations/it.json | 2 ++ guacamole/src/main/webapp/translations/nl.json | 2 ++ guacamole/src/main/webapp/translations/no.json | 2 ++ guacamole/src/main/webapp/translations/ru.json | 2 ++ guacamole/src/main/webapp/translations/zh.json | 2 ++ 12 files changed, 52 insertions(+), 1 deletion(-) diff --git a/guacamole/src/main/webapp/app/client/controllers/clientController.js b/guacamole/src/main/webapp/app/client/controllers/clientController.js index 11ded35fc..94da2e3ec 100644 --- a/guacamole/src/main/webapp/app/client/controllers/clientController.js +++ b/guacamole/src/main/webapp/app/client/controllers/clientController.js @@ -288,6 +288,24 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams */ $scope.rootConnectionGroups = null; + /** + * Array of all connection properties that are filterable. + * + * @type String[] + */ + $scope.filteredConnectionProperties = [ + 'name' + ]; + + /** + * Array of all connection group properties that are filterable. + * + * @type String[] + */ + $scope.filteredConnectionGroupProperties = [ + 'name' + ]; + // Retrieve root groups and all descendants dataSourceService.apply( connectionGroupService.getConnectionGroupTree, diff --git a/guacamole/src/main/webapp/app/client/styles/guac-menu.css b/guacamole/src/main/webapp/app/client/styles/guac-menu.css index 73562ceb8..48fb3b372 100644 --- a/guacamole/src/main/webapp/app/client/styles/guac-menu.css +++ b/guacamole/src/main/webapp/app/client/styles/guac-menu.css @@ -78,6 +78,16 @@ font-size: 0.8em; } +#guac-menu .header .filter input { + border-bottom: 1px solid rgba(0,0,0,0.125); + border-left: none; +} + +#guac-menu .header .filter { + margin-bottom: 0.5em; + padding: 0; +} + #guac-menu #mouse-settings .choice { text-align: center; } diff --git a/guacamole/src/main/webapp/app/client/templates/client.html b/guacamole/src/main/webapp/app/client/templates/client.html index 6e40461e4..9d06549f9 100644 --- a/guacamole/src/main/webapp/app/client/templates/client.html +++ b/guacamole/src/main/webapp/app/client/templates/client.html @@ -56,8 +56,13 @@

+ Date: Tue, 2 Apr 2019 09:20:45 -0700 Subject: [PATCH 13/17] GUACAMOLE-723: Sort connections in panel by last use. --- .../webapp/app/client/controllers/clientController.js | 6 ++++++ .../webapp/app/client/templates/guacClientPanel.html | 8 ++++---- .../src/main/webapp/app/client/types/ManagedClient.js | 10 ++++++++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/guacamole/src/main/webapp/app/client/controllers/clientController.js b/guacamole/src/main/webapp/app/client/controllers/clientController.js index 94da2e3ec..5ee084b6e 100644 --- a/guacamole/src/main/webapp/app/client/controllers/clientController.js +++ b/guacamole/src/main/webapp/app/client/controllers/clientController.js @@ -492,6 +492,12 @@ angular.module('client').controller('clientController', ['$scope', '$routeParams }); + // Update last used timestamp when the active client changes + $scope.$watch('client', function clientChanged(client) { + if (client) + client.lastUsed = new Date().getTime(); + }); + // Update page icon when thumbnail changes $scope.$watch('client.thumbnail.canvas', function thumbnailChanged(canvas) { iconService.setIcons(canvas); diff --git a/guacamole/src/main/webapp/app/client/templates/guacClientPanel.html b/guacamole/src/main/webapp/app/client/templates/guacClientPanel.html index e550c849f..00dfddef9 100644 --- a/guacamole/src/main/webapp/app/client/templates/guacClientPanel.html +++ b/guacamole/src/main/webapp/app/client/templates/guacClientPanel.html @@ -6,12 +6,12 @@ diff --git a/guacamole/src/main/webapp/app/client/types/ManagedClient.js b/guacamole/src/main/webapp/app/client/types/ManagedClient.js index a9bc3beac..288931175 100644 --- a/guacamole/src/main/webapp/app/client/types/ManagedClient.js +++ b/guacamole/src/main/webapp/app/client/types/ManagedClient.js @@ -79,6 +79,16 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector', */ this.id = template.id; + /** + * The time that the connection was last brought to the foreground of + * the current tab, as the number of milliseconds elapsed since + * midnight of January 1, 1970 UTC. If the connection has not yet been + * viewed, this will be 0. + * + * @type Number + */ + this.lastUsed = template.lastUsed || 0; + /** * The actual underlying Guacamole client. * From d7dfd08add13888b93ab37172cc3cd3d44f59e69 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 2 Apr 2019 11:14:23 -0700 Subject: [PATCH 14/17] GUACAMOLE-723: Display warning icon when background connection disconnects due to an error. --- .../app/client/directives/guacClientPanel.js | 28 ++++++++++++++++++ .../app/client/styles/other-connections.css | 25 ++++++++++++++++ .../app/client/templates/guacClientPanel.html | 3 +- .../src/main/webapp/images/warning-white.png | Bin 0 -> 4506 bytes 4 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 guacamole/src/main/webapp/images/warning-white.png diff --git a/guacamole/src/main/webapp/app/client/directives/guacClientPanel.js b/guacamole/src/main/webapp/app/client/directives/guacClientPanel.js index 737fce9c4..5cd30ec01 100644 --- a/guacamole/src/main/webapp/app/client/directives/guacClientPanel.js +++ b/guacamole/src/main/webapp/app/client/directives/guacClientPanel.js @@ -24,8 +24,12 @@ */ angular.module('client').directive('guacClientPanel', ['$injector', function guacClientPanel($injector) { + // Required services var sessionStorageFactory = $injector.get('sessionStorageFactory'); + // Required types + var ManagedClientState = $injector.get('ManagedClientState'); + /** * Getter/setter for the boolean flag controlling whether the client panel * is currently hidden. This flag is maintained in session-local storage to @@ -81,6 +85,30 @@ angular.module('client').directive('guacClientPanel', ['$injector', function gua return !_.isEmpty($scope.clients); }; + /** + * Returns whether the given client has disconnected due to an + * error. + * + * @param {ManagedClient} client + * The client to test. + * + * @returns {Boolean} + * true if the given client has disconnected due to an error, + * false otherwise. + */ + $scope.hasError = function hasError(client) { + + // Test whether the client has encountered an error + switch (client.clientState.connectionState) { + case ManagedClientState.ConnectionState.CONNECTION_ERROR: + case ManagedClientState.ConnectionState.TUNNEL_ERROR: + return true; + } + + return false; + + }; + /** * Toggles whether the client panel is currently hidden. */ diff --git a/guacamole/src/main/webapp/app/client/styles/other-connections.css b/guacamole/src/main/webapp/app/client/styles/other-connections.css index 41069ded4..d726b540f 100644 --- a/guacamole/src/main/webapp/app/client/styles/other-connections.css +++ b/guacamole/src/main/webapp/app/client/styles/other-connections.css @@ -100,6 +100,31 @@ } +#other-connections .client-panel-connection::before { + + display: block; + content: ' '; + + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + + background: url('images/warning-white.png'); + background-size: 48px; + background-position: center; + background-repeat: no-repeat; + + opacity: 0; + transition: opacity 0.25s; + +} + +#other-connections .client-panel-connection.error::before { + opacity: 0.75; +} + #other-connections .client-panel.hidden .client-panel-connection-list { /* Hide scrollbar when panel is hidden (will be visible through panel * show/hide button otherwise) */ diff --git a/guacamole/src/main/webapp/app/client/templates/guacClientPanel.html b/guacamole/src/main/webapp/app/client/templates/guacClientPanel.html index 00dfddef9..a09033510 100644 --- a/guacamole/src/main/webapp/app/client/templates/guacClientPanel.html +++ b/guacamole/src/main/webapp/app/client/templates/guacClientPanel.html @@ -6,7 +6,8 @@