From 012663ed9aa7235749400649e156aee27e0136a9 Mon Sep 17 00:00:00 2001 From: James Muehlner Date: Tue, 2 Jan 2024 21:21:47 +0000 Subject: [PATCH 1/6] GUACAMOLE-1904: Pass the client directly to the field to allow saving field values. --- .../main/frontend/src/app/client/templates/client.html | 1 + .../src/main/frontend/src/app/form/directives/form.js | 9 ++++++++- .../main/frontend/src/app/form/directives/formField.js | 9 ++++++++- .../src/main/frontend/src/app/form/templates/form.html | 1 + 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/guacamole/src/main/frontend/src/app/client/templates/client.html b/guacamole/src/main/frontend/src/app/client/templates/client.html index 829d5ef7d..66dca3a77 100644 --- a/guacamole/src/main/frontend/src/app/client/templates/client.html +++ b/guacamole/src/main/frontend/src/app/client/templates/client.html @@ -124,6 +124,7 @@ diff --git a/guacamole/src/main/frontend/src/app/form/directives/form.js b/guacamole/src/main/frontend/src/app/form/directives/form.js index 8d35774c7..4aa99668a 100644 --- a/guacamole/src/main/frontend/src/app/form/directives/form.js +++ b/guacamole/src/main/frontend/src/app/form/directives/form.js @@ -79,7 +79,14 @@ angular.module('form').directive('guacForm', [function form() { * * @type String */ - focused : '=' + focused : '=', + + /** + * The client associated with this form, if any. + * + * @type ManagedClient + */ + client: '=' }, templateUrl: 'app/form/templates/form.html', diff --git a/guacamole/src/main/frontend/src/app/form/directives/formField.js b/guacamole/src/main/frontend/src/app/form/directives/formField.js index 4fcead1d6..73ffb127e 100644 --- a/guacamole/src/main/frontend/src/app/form/directives/formField.js +++ b/guacamole/src/main/frontend/src/app/form/directives/formField.js @@ -68,7 +68,14 @@ angular.module('form').directive('guacFormField', [function formField() { * * @type Boolean */ - focused : '=' + focused : '=', + + /** + * The client associated with this form field, if any. + * + * @type ManagedClient + */ + client: '=' }, templateUrl: 'app/form/templates/formField.html', diff --git a/guacamole/src/main/frontend/src/app/form/templates/form.html b/guacamole/src/main/frontend/src/app/form/templates/form.html index 397a210c5..084d55df9 100644 --- a/guacamole/src/main/frontend/src/app/form/templates/form.html +++ b/guacamole/src/main/frontend/src/app/form/templates/form.html @@ -13,6 +13,7 @@ data-disabled="disabled" focused="isFocused(field)" field="field" + client="client" model="values[field.name]"> From 15b88dd4f4edb0b53eb240a4c6b6f14a9049df48 Mon Sep 17 00:00:00 2001 From: James Muehlner Date: Tue, 9 Jan 2024 01:17:28 +0000 Subject: [PATCH 2/6] GUACAMOLE-1904: Disable ManagedArgument instead of deleting when updated, to avoid fields disappearing upon modification. --- .../src/app/client/types/ManagedArgument.js | 35 ++++++++++--------- .../src/app/client/types/ManagedClient.js | 5 ++- .../frontend/src/app/form/directives/form.js | 28 +++++++++++++++ .../frontend/src/app/form/templates/form.html | 2 +- 4 files changed, 49 insertions(+), 21 deletions(-) diff --git a/guacamole/src/main/frontend/src/app/client/types/ManagedArgument.js b/guacamole/src/main/frontend/src/app/client/types/ManagedArgument.js index 247d9f679..5e676bfcb 100644 --- a/guacamole/src/main/frontend/src/app/client/types/ManagedArgument.js +++ b/guacamole/src/main/frontend/src/app/client/types/ManagedArgument.js @@ -58,6 +58,16 @@ angular.module('client').factory('ManagedArgument', ['$q', function defineManage */ this.stream = template.stream; + /** + * True if this argument has been modified in the webapp, but yet to + * be confirmed by guacd, or false in any other case. A pending + * argument cannot be modified again, and must be recreated before + * editing is enabled again. + * + * @type {boolean} + */ + this.pending = false; + }; /** @@ -110,9 +120,9 @@ angular.module('client').factory('ManagedArgument', ['$q', function defineManage * Sets the given editable argument (connection parameter) to the given * value, updating the behavior of the associated connection in real-time. * If successful, the ManagedArgument provided cannot be used for future - * calls to setValue() and must be replaced with a new instance. This - * function only has an effect if the new parameter value is different from - * the current value. + * calls to setValue() and will be read-only until replaced with a new + * instance. This function only has an effect if the new parameter value + * is different from the current value. * * @param {ManagedArgument} managedArgument * The ManagedArgument instance associated with the connection @@ -120,33 +130,24 @@ angular.module('client').factory('ManagedArgument', ['$q', function defineManage * * @param {String} value * The new value to assign to the connection parameter. - * - * @returns {Boolean} - * true if the connection parameter was sent and the provided - * ManagedArgument instance may no longer be used for future setValue() - * calls, false if the connection parameter was NOT sent as it has not - * changed. */ ManagedArgument.setValue = function setValue(managedArgument, value) { - // Stream new value only if value has changed - if (value !== managedArgument.value) { + // Stream new value only if value has changed and a change is not + // already pending + if (!managedArgument.pending && value !== managedArgument.value) { var writer = new Guacamole.StringWriter(managedArgument.stream); writer.sendText(value); writer.sendEnd(); // ManagedArgument instance is no longer usable - return true; + managedArgument.pending = true; } - // No parameter value change was attempted and the ManagedArgument - // instance may be reused - return false; - }; return ManagedArgument; -}]); \ No newline at end of file +}]); diff --git a/guacamole/src/main/frontend/src/app/client/types/ManagedClient.js b/guacamole/src/main/frontend/src/app/client/types/ManagedClient.js index 5dc8bce44..01769ea94 100644 --- a/guacamole/src/main/frontend/src/app/client/types/ManagedClient.js +++ b/guacamole/src/main/frontend/src/app/client/types/ManagedClient.js @@ -836,8 +836,7 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector', */ ManagedClient.setArgument = function setArgument(managedClient, name, value) { var managedArgument = managedClient.arguments[name]; - if (managedArgument && ManagedArgument.setValue(managedArgument, value)) - delete managedClient.arguments[name]; + managedArgument && ManagedArgument.setValue(managedArgument, value); }; /** @@ -1007,4 +1006,4 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector', return ManagedClient; -}]); \ No newline at end of file +}]); diff --git a/guacamole/src/main/frontend/src/app/form/directives/form.js b/guacamole/src/main/frontend/src/app/form/directives/form.js index 4aa99668a..4de051bfd 100644 --- a/guacamole/src/main/frontend/src/app/form/directives/form.js +++ b/guacamole/src/main/frontend/src/app/form/directives/form.js @@ -17,6 +17,7 @@ * under the License. */ +/* global _ */ /** * A directive that allows editing of a collection of fields. @@ -84,6 +85,11 @@ angular.module('form').directive('guacForm', [function form() { /** * The client associated with this form, if any. * + * NOTE: If the provided client has any managed arguments in the + * pending state, any fields with the same name rendered by this + * form will be disabled. The fields will be re-enabled when guacd + * sends an updated argument with a the same name. + * * @type ManagedClient */ client: '=' @@ -247,6 +253,28 @@ angular.module('form').directive('guacForm', [function form() { }; + + /** + * Returns whether the given field should be disabled (read-only) + * when presented to the current user. + * + * @param {Field} field + * The field to check. + * + * @returns {Boolean} + * true if the given field should be disabled, false otherwise. + */ + $scope.isDisabled = function isDisabled(field) { + + /* + * The field is disabled if either the form as a whole is disabled, + * or if a client is provided to the directive, and the field is + * marked as pending. + */ + return $scope.disabled || + _.get($scope.client, ['arguments', field.name, 'pending']); + }; + /** * Returns whether at least one of the given fields should be * displayed to the current user. diff --git a/guacamole/src/main/frontend/src/app/form/templates/form.html b/guacamole/src/main/frontend/src/app/form/templates/form.html index 084d55df9..642c57783 100644 --- a/guacamole/src/main/frontend/src/app/form/templates/form.html +++ b/guacamole/src/main/frontend/src/app/form/templates/form.html @@ -10,7 +10,7 @@
Date: Tue, 9 Jan 2024 20:16:37 +0000 Subject: [PATCH 3/6] GUACAMOLE-1904: Always render client menu even if not shown. --- .../main/frontend/src/app/client/styles/menu.css | 14 +++++++------- .../frontend/src/app/client/templates/client.html | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/guacamole/src/main/frontend/src/app/client/styles/menu.css b/guacamole/src/main/frontend/src/app/client/styles/menu.css index b5742ab5d..81552b168 100644 --- a/guacamole/src/main/frontend/src/app/client/styles/menu.css +++ b/guacamole/src/main/frontend/src/app/client/styles/menu.css @@ -27,11 +27,11 @@ background: #EEE; box-shadow: inset -1px 0 2px white, 1px 0 2px black; z-index: 100; - -webkit-transition: left 0.125s, opacity 0.125s; - -moz-transition: left 0.125s, opacity 0.125s; - -ms-transition: left 0.125s, opacity 0.125s; - -o-transition: left 0.125s, opacity 0.125s; - transition: left 0.125s, opacity 0.125s; + -webkit-transition: left 0.125s; + -moz-transition: left 0.125s; + -ms-transition: left 0.125s; + -o-transition: left 0.125s; + transition: left 0.125s; } .menu-content { @@ -137,10 +137,10 @@ .menu, .menu.closed { left: -480px; - opacity: 0; + visibility: hidden; } .menu.open { left: 0px; - opacity: 1; + visibility: visible; } diff --git a/guacamole/src/main/frontend/src/app/client/templates/client.html b/guacamole/src/main/frontend/src/app/client/templates/client.html index 66dca3a77..943e59953 100644 --- a/guacamole/src/main/frontend/src/app/client/templates/client.html +++ b/guacamole/src/main/frontend/src/app/client/templates/client.html @@ -47,7 +47,7 @@