diff --git a/guacamole/src/main/webapp/app/manage/controllers/connectionEditModalController.js b/guacamole/src/main/webapp/app/manage/controllers/connectionEditModalController.js index fea764da2..fd943217c 100644 --- a/guacamole/src/main/webapp/app/manage/controllers/connectionEditModalController.js +++ b/guacamole/src/main/webapp/app/manage/controllers/connectionEditModalController.js @@ -36,6 +36,7 @@ angular.module('manage').controller('connectionEditModalController', ['$scope', // Copy data into a new conection object in case the user doesn't want to save $scope.connection = new Connection($scope.connection); + $scope.connection.parameters = {}; var newConnection = !$scope.connection.identifier; @@ -47,11 +48,17 @@ angular.module('manage').controller('connectionEditModalController', ['$scope', // Wrap all the history entries if (!newConnection) { + connectionService.getConnectionHistory($scope.connection.identifier).success(function wrapHistoryEntries(historyEntries) { historyEntries.forEach(function wrapHistoryEntry(historyEntry) { $scope.historyEntryWrappers.push(new HistoryEntryWrapper(historyEntry)); }); }); + + connectionService.getConnectionParameters($scope.connection.identifier).success(function setParameters(parameters) { + $scope.connection.parameters = parameters; + }); + } /** diff --git a/guacamole/src/main/webapp/app/manage/directives/connectionParameter.js b/guacamole/src/main/webapp/app/manage/directives/connectionParameter.js index f3f931017..c720ecc17 100644 --- a/guacamole/src/main/webapp/app/manage/directives/connectionParameter.js +++ b/guacamole/src/main/webapp/app/manage/directives/connectionParameter.js @@ -31,55 +31,128 @@ angular.module('manage').directive('guacConnectionParameter', [function connecti restrict: 'E', replace: true, scope: { - parameter: '=parameter', - connection: '=connection', + + /** + * The protocol this parameter is associated with. + * + * @type Protocol + */ + protocol : '=', + + /** + * The unique name of this parameter within the protocol + * definition. + * + * @type String + */ + name : '=', + + /** + * The current map of parameter names to their corresponding string + * values. + * + * @type Object. + */ + parameters : '=' + }, templateUrl: 'app/manage/templates/connectionParameter.html', - controller: ['$scope', function connectionParameterController($scope) { - $scope.connectionParameters = $scope.connection.parameters; - $scope.parameterType = $scope.parameter.type; - $scope.parameterName = $scope.parameter.name; - - // Coerce numeric strings to numbers - if ($scope.parameterType === 'NUMERIC') { - - // If a value exists, coerce it to a number - if ($scope.connectionParameters[$scope.parameterName]) - $scope.parameterValue = Number($scope.connectionParameters[$scope.parameterName]); - else - $scope.parameterValue = null; - - } - - // Coerce boolean strings to boolean values - else if ($scope.parameterType === 'BOOLEAN') { - // TODO: Use defined checked value from protocol description - $scope.parameterValue = $scope.connectionParameters[$scope.parameterName] === 'true'; - } - - // All other parameter types are represented internally as strings - else - $scope.parameterValue = $scope.connectionParameters[$scope.parameterName]; - - // Update internal representation as model is changed - $scope.$watch('parameterValue', function parameterValueChanges(value) { - - // Convert numeric values back into strings - if ($scope.parameterType === 'NUMERIC') { - if (value === null || typeof value === 'undefined') - $scope.connectionParameters[$scope.parameterName] = ''; + controller: ['$scope', '$q', function connectionParameterController($scope, $q) { + + /** + * Deferred load of the parameter definition, pending availability + * of the protocol definition as a whole. + * + * @type Deferred + */ + var parameterDefinitionAvailable = $q.defer(); + + /** + * Populates the parameter definition on the scope as + * $scope.parameter if both the parameter name and + * protocol definition are available. If either are unavailable, + * this function has no effect. + */ + var retrieveParameterDefinition = function retrieveParameterDefinition() { + + // Both name and protocol are needed to retrieve the parameter definition + if (!$scope.name || !$scope.protocol) + return; + + // Once protocol definition is available, locate parameter definition by name + $scope.protocol.parameters.forEach(function findParameter(parameter) { + if (parameter.name === $scope.name) { + $scope.parameter = parameter; + parameterDefinitionAvailable.resolve(parameter); + } + }); + + }; + + // Load parameter definition once protocol definition is available. + $scope.$watch('name', retrieveParameterDefinition); + $scope.$watch('protocol', retrieveParameterDefinition); + + // Update typed value when parameter set is changed + $scope.$watch('parameters', function setParameters(parameters) { + + // Don't bother if no parameters were provided + if (!parameters) + return; + + // Wait for parameter definition + parameterDefinitionAvailable.promise.then(function setTypedValue() { + + // Pull parameter value + var value = parameters[$scope.name]; + + // Coerce numeric strings to numbers + if ($scope.parameter.type === 'NUMERIC') + $scope.typedValue = (value ? Number(value) : null); + + // Coerce boolean strings to boolean values + else if ($scope.parameter.type === 'BOOLEAN') + $scope.typedValue = (value === $scope.parameter.value); + + // All other parameter types are represented internally as strings else - $scope.connectionParameters[$scope.parameterName] = value.toString(); - } - - // TODO: Transform BOOLEAN input fields back into strings based on protocol description - - // All other parameter types are already strings - else - $scope.connectionParameters[$scope.parameterName] = value; - + $scope.typedValue = value || ''; + + }); + }); - }] + + // Update string value in parameter set when typed value is changed + $scope.$watch('typedValue', function typedValueChanged(typedValue) { + + // Don't bother if there's nothing to set + if (!$scope.parameters) + return; + + // Wait for parameter definition + parameterDefinitionAvailable.promise.then(function setValue() { + + // Convert numeric values back into strings + if ($scope.parameter.type === 'NUMERIC') { + if (!typedValue) + $scope.parameters[$scope.name] = ''; + else + $scope.parameters[$scope.name] = typedValue.toString(); + } + + // Convert boolean values back into strings based on protocol description + else if ($scope.parameter.type === 'BOOLEAN') + $scope.parameters[$scope.name] = (typedValue ? $scope.parameter.value : ''); + + // All other parameter types are already strings + else + $scope.parameters[$scope.name] = typedValue || ''; + + }); + + }); // end watch typedValue + + }] // end controller }; }]); \ No newline at end of file diff --git a/guacamole/src/main/webapp/app/manage/templates/connectionParameter.html b/guacamole/src/main/webapp/app/manage/templates/connectionParameter.html index 4249f3a3a..540f7e5fa 100644 --- a/guacamole/src/main/webapp/app/manage/templates/connectionParameter.html +++ b/guacamole/src/main/webapp/app/manage/templates/connectionParameter.html @@ -20,10 +20,11 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --> - - - - - - + + + + + + + \ No newline at end of file diff --git a/guacamole/src/main/webapp/app/manage/templates/editableConnection.html b/guacamole/src/main/webapp/app/manage/templates/editableConnection.html index a46883c2d..213b33c02 100644 --- a/guacamole/src/main/webapp/app/manage/templates/editableConnection.html +++ b/guacamole/src/main/webapp/app/manage/templates/editableConnection.html @@ -72,7 +72,7 @@ THE SOFTWARE. {{'protocol.' + connection.protocol + '.parameters.' + parameter.name + '.label' | translate}}: - + diff --git a/guacamole/src/main/webapp/app/rest/services/protocolService.js b/guacamole/src/main/webapp/app/rest/services/protocolService.js index 1a863107a..b03acd53b 100644 --- a/guacamole/src/main/webapp/app/rest/services/protocolService.js +++ b/guacamole/src/main/webapp/app/rest/services/protocolService.js @@ -30,12 +30,12 @@ angular.module('rest').factory('protocolService', ['$http', 'authenticationServi /** * Makes a request to the REST API to get the list of protocols, returning - * a promise that provides an array of @link{Protocol} objects if - * successful. + * a promise that provides a map of @link{Protocol} objects by protocol + * name if successful. * - * @returns {Promise.} - * A promise which will resolve with an array of @link{Protocol} - * objects upon success. + * @returns {Promise.>} + * A promise which will resolve with a map of @link{Protocol} + * objects by protocol name upon success. */ service.getProtocols = function getProtocols() {