mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-08 06:01:22 +00:00
Merge pull request #147 from glyptodon/generalize-fields
GUAC-1106: Create generalized form module and directives
This commit is contained in:
120
guacamole/src/main/webapp/app/form/directives/form.js
Normal file
120
guacamole/src/main/webapp/app/form/directives/form.js
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* 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 that allows editing of a collection of fields.
|
||||||
|
*/
|
||||||
|
angular.module('form').directive('guacForm', [function form() {
|
||||||
|
|
||||||
|
return {
|
||||||
|
// Element only
|
||||||
|
restrict: 'E',
|
||||||
|
replace: true,
|
||||||
|
scope: {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The translation namespace of the translation strings that will
|
||||||
|
* be generated for all fields. This namespace is absolutely
|
||||||
|
* required. If this namespace is omitted, all generated
|
||||||
|
* translation strings will be placed within the MISSING_NAMESPACE
|
||||||
|
* namespace, as a warning.
|
||||||
|
*
|
||||||
|
* @type String
|
||||||
|
*/
|
||||||
|
namespace : '=',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fields to display.
|
||||||
|
*
|
||||||
|
* @type Field[]
|
||||||
|
*/
|
||||||
|
fields : '=',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The object which will receive all field values. Each field value
|
||||||
|
* will be assigned to the property of this object having the same
|
||||||
|
* name.
|
||||||
|
*
|
||||||
|
* @type Object.<String, String>
|
||||||
|
*/
|
||||||
|
model : '='
|
||||||
|
|
||||||
|
},
|
||||||
|
templateUrl: 'app/form/templates/form.html',
|
||||||
|
controller: ['$scope', '$injector', function formController($scope, $injector) {
|
||||||
|
|
||||||
|
// Required services
|
||||||
|
var translationStringService = $injector.get('translationStringService');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The object which will receive all field values. Normally, this
|
||||||
|
* will be the object provided within the "model" attribute. If
|
||||||
|
* no such object has been provided, a blank model will be used
|
||||||
|
* instead as a placeholder, such that the fields of this form
|
||||||
|
* will have something to bind to.
|
||||||
|
*
|
||||||
|
* @type Object.<String, String>
|
||||||
|
*/
|
||||||
|
$scope.values = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Produces the translation string for the header of the given
|
||||||
|
* field. The translation string will be of the form:
|
||||||
|
*
|
||||||
|
* <code>NAMESPACE.FIELD_HEADER_NAME<code>
|
||||||
|
*
|
||||||
|
* where <code>NAMESPACE</code> is the namespace provided to the
|
||||||
|
* directive and <code>NAME</code> is the field name transformed
|
||||||
|
* via translationStringService.canonicalize().
|
||||||
|
*
|
||||||
|
* @param {Field} field
|
||||||
|
* The field for which to produce the translation string.
|
||||||
|
*
|
||||||
|
* @returns {String}
|
||||||
|
* The translation string which produces the translated header
|
||||||
|
* of the field.
|
||||||
|
*/
|
||||||
|
$scope.getFieldHeader = function getFieldHeader(field) {
|
||||||
|
|
||||||
|
return translationStringService.canonicalize($scope.namespace || 'MISSING_NAMESPACE')
|
||||||
|
+ '.FIELD_HEADER_' + translationStringService.canonicalize(field.name);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update string value and re-assign to model when field is changed
|
||||||
|
$scope.$watch('model', function setModel(model) {
|
||||||
|
|
||||||
|
// Assign new model only if provided
|
||||||
|
if (model)
|
||||||
|
$scope.values = model;
|
||||||
|
|
||||||
|
// Otherwise, use blank model
|
||||||
|
else
|
||||||
|
$scope.values = {};
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}] // end controller
|
||||||
|
};
|
||||||
|
|
||||||
|
}]);
|
225
guacamole/src/main/webapp/app/form/directives/formField.js
Normal file
225
guacamole/src/main/webapp/app/form/directives/formField.js
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 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 that allows editing of a field.
|
||||||
|
*/
|
||||||
|
angular.module('form').directive('guacFormField', [function formField() {
|
||||||
|
|
||||||
|
return {
|
||||||
|
// Element only
|
||||||
|
restrict: 'E',
|
||||||
|
replace: true,
|
||||||
|
scope: {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The translation namespace of the translation strings that will
|
||||||
|
* be generated for this field. This namespace is absolutely
|
||||||
|
* required. If this namespace is omitted, all generated
|
||||||
|
* translation strings will be placed within the MISSING_NAMESPACE
|
||||||
|
* namespace, as a warning.
|
||||||
|
*
|
||||||
|
* @type String
|
||||||
|
*/
|
||||||
|
namespace : '=',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The field to display.
|
||||||
|
*
|
||||||
|
* @type Field
|
||||||
|
*/
|
||||||
|
field : '=',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The property which contains this fields current value. When this
|
||||||
|
* field changes, the property will be updated accordingly.
|
||||||
|
*
|
||||||
|
* @type String
|
||||||
|
*/
|
||||||
|
model : '='
|
||||||
|
|
||||||
|
},
|
||||||
|
templateUrl: 'app/form/templates/formField.html',
|
||||||
|
controller: ['$scope', '$injector', function formFieldController($scope, $injector) {
|
||||||
|
|
||||||
|
// Required services
|
||||||
|
var translationStringService = $injector.get('translationStringService');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type to use for password input fields. By default, password
|
||||||
|
* input fields have type 'password', and are thus masked.
|
||||||
|
*
|
||||||
|
* @type String
|
||||||
|
* @default 'password'
|
||||||
|
*/
|
||||||
|
$scope.passwordInputType = 'password';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string which describes the action the next call to
|
||||||
|
* togglePassword() will have.
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
|
* A string which describes the action the next call to
|
||||||
|
* togglePassword() will have.
|
||||||
|
*/
|
||||||
|
$scope.getTogglePasswordHelpText = function getTogglePasswordHelpText() {
|
||||||
|
|
||||||
|
// If password is hidden, togglePassword() will show the password
|
||||||
|
if ($scope.passwordInputType === 'password')
|
||||||
|
return 'FORM.HELP_SHOW_PASSWORD';
|
||||||
|
|
||||||
|
// If password is shown, togglePassword() will hide the password
|
||||||
|
return 'FORM.HELP_HIDE_PASSWORD';
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles visibility of the field contents, if this field is a
|
||||||
|
* password field. Initially, password contents are masked
|
||||||
|
* (invisible).
|
||||||
|
*/
|
||||||
|
$scope.togglePassword = function togglePassword() {
|
||||||
|
|
||||||
|
// If password is hidden, show the password
|
||||||
|
if ($scope.passwordInputType === 'password')
|
||||||
|
$scope.passwordInputType = 'text';
|
||||||
|
|
||||||
|
// If password is shown, hide the password
|
||||||
|
else
|
||||||
|
$scope.passwordInputType = 'password';
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Produces the translation string for the given field option
|
||||||
|
* value. The translation string will be of the form:
|
||||||
|
*
|
||||||
|
* <code>NAMESPACE.FIELD_OPTION_NAME_VALUE<code>
|
||||||
|
*
|
||||||
|
* where <code>NAMESPACE</code> is the namespace provided to the
|
||||||
|
* directive, <code>NAME</code> is the field name transformed
|
||||||
|
* via translationStringService.canonicalize(), and
|
||||||
|
* <code>VALUE</code> is the option value transformed via
|
||||||
|
* translationStringService.canonicalize()
|
||||||
|
*
|
||||||
|
* @param {String} value
|
||||||
|
* The name of the option value.
|
||||||
|
*
|
||||||
|
* @returns {String}
|
||||||
|
* The translation string which produces the translated name of the
|
||||||
|
* value specified.
|
||||||
|
*/
|
||||||
|
$scope.getFieldOption = function getFieldOption(value) {
|
||||||
|
|
||||||
|
// Don't bother if the model is not yet defined
|
||||||
|
if (!$scope.field)
|
||||||
|
return '';
|
||||||
|
|
||||||
|
return translationStringService.canonicalize($scope.namespace || 'MISSING_NAMESPACE')
|
||||||
|
+ '.FIELD_OPTION_' + translationStringService.canonicalize($scope.field.name)
|
||||||
|
+ '_' + translationStringService.canonicalize(value || 'EMPTY');
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates the given string field value into an appropriately-
|
||||||
|
* typed value as dictated by the attributes of the field,
|
||||||
|
* exposing that typed value within the scope as
|
||||||
|
* <code>$scope.typedValue<code>.
|
||||||
|
*
|
||||||
|
* @param {String} modelValue
|
||||||
|
* The current string value of the field.
|
||||||
|
*/
|
||||||
|
var setTypedValue = function setTypedValue(modelValue) {
|
||||||
|
|
||||||
|
// Don't bother if the model is not yet defined
|
||||||
|
if (!$scope.field)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Coerce numeric strings to numbers
|
||||||
|
if ($scope.field.type === 'NUMERIC')
|
||||||
|
$scope.typedValue = (modelValue ? Number($scope.field.value) : null);
|
||||||
|
|
||||||
|
// Coerce boolean strings to boolean values
|
||||||
|
else if ($scope.field.type === 'BOOLEAN')
|
||||||
|
$scope.typedValue = (modelValue === $scope.field.value);
|
||||||
|
|
||||||
|
// All other field types are represented internally as strings
|
||||||
|
else
|
||||||
|
$scope.typedValue = modelValue || '';
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates the given typed field value into a string as dictated
|
||||||
|
* by the attributes of the field, assigning that string value to
|
||||||
|
* the model.
|
||||||
|
*
|
||||||
|
* @param {String|Number|Boolean} typedValue
|
||||||
|
* The current value of the field, as an appropriate JavaScript
|
||||||
|
* type.
|
||||||
|
*/
|
||||||
|
var setModelValue = function setModelValue(typedValue) {
|
||||||
|
|
||||||
|
// Don't bother if the model is not yet defined
|
||||||
|
if (!$scope.field)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Convert numeric values back into strings
|
||||||
|
if ($scope.field.type === 'NUMERIC') {
|
||||||
|
if (!typedValue)
|
||||||
|
$scope.model = '';
|
||||||
|
else
|
||||||
|
$scope.model = typedValue.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert boolean values back into strings based on field description
|
||||||
|
else if ($scope.field.type === 'BOOLEAN')
|
||||||
|
$scope.model = (typedValue ? $scope.field.value : '');
|
||||||
|
|
||||||
|
// All other field types are already strings
|
||||||
|
else
|
||||||
|
$scope.model = typedValue || '';
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update string value and re-assign to model when field is changed
|
||||||
|
$scope.$watch('field', function setField(field) {
|
||||||
|
setTypedValue($scope.model);
|
||||||
|
setModelValue($scope.typedValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update typed value when model is changed
|
||||||
|
$scope.$watch('model', function setModel(model) {
|
||||||
|
setTypedValue(model);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update string value in model when typed value is changed
|
||||||
|
$scope.$watch('typedValue', function typedValueChanged(typedValue) {
|
||||||
|
setModelValue(typedValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
}] // end controller
|
||||||
|
};
|
||||||
|
|
||||||
|
}]);
|
26
guacamole/src/main/webapp/app/form/formModule.js
Normal file
26
guacamole/src/main/webapp/app/form/formModule.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module for displaying dynamic forms.
|
||||||
|
*/
|
||||||
|
angular.module('form', ['locale']);
|
50
guacamole/src/main/webapp/app/form/styles/form-field.css
Normal file
50
guacamole/src/main/webapp/app/form/styles/form-field.css
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Keep toggle-password icon on same line */
|
||||||
|
.form-field .password-field {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generic 1x1em icon/button */
|
||||||
|
.form-field .password-field .icon.toggle-password {
|
||||||
|
|
||||||
|
display: inline-block;
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: default;
|
||||||
|
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 1em;
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Icon for unmasking passwords */
|
||||||
|
.form-field .password-field input[type=password] ~ .icon.toggle-password {
|
||||||
|
background-image: url('images/action-icons/guac-show-pass.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Icon for masking passwords */
|
||||||
|
.form-field .password-field input[type=text] ~ .icon.toggle-password {
|
||||||
|
background-image: url('images/action-icons/guac-hide-pass.png');
|
||||||
|
}
|
27
guacamole/src/main/webapp/app/form/styles/form.css
Normal file
27
guacamole/src/main/webapp/app/form/styles/form.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
table.form th {
|
||||||
|
text-align: left;
|
||||||
|
font-weight: normal;
|
||||||
|
padding-right: 1em;
|
||||||
|
}
|
32
guacamole/src/main/webapp/app/form/templates/form.html
Normal file
32
guacamole/src/main/webapp/app/form/templates/form.html
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<table class="form">
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- All fields in form -->
|
||||||
|
<tr ng-repeat="field in fields">
|
||||||
|
<th>{{getFieldHeader(field) | translate}}</th>
|
||||||
|
<td>
|
||||||
|
<guac-form-field namespace="namespace" field="field" model="values[field.name]"></guac-form-field>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</table>
|
@@ -1,4 +1,4 @@
|
|||||||
<div class="connection-parameter">
|
<div class="form-field">
|
||||||
<!--
|
<!--
|
||||||
Copyright 2014 Glyptodon LLC.
|
Copyright 2014 Glyptodon LLC.
|
||||||
|
|
||||||
@@ -22,21 +22,21 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- Generic input types -->
|
<!-- Generic input types -->
|
||||||
<input ng-show="parameter.type === 'TEXT'" type="text" ng-model="typedValue" autocorrect="off" autocapitalize="off"/>
|
<input ng-show="field.type === 'TEXT'" type="text" ng-model="typedValue" autocorrect="off" autocapitalize="off"/>
|
||||||
<input ng-show="parameter.type === 'NUMERIC'" type="number" ng-model="typedValue" autocorrect="off" autocapitalize="off"/>
|
<input ng-show="field.type === 'NUMERIC'" type="number" ng-model="typedValue" autocorrect="off" autocapitalize="off"/>
|
||||||
<input ng-show="parameter.type === 'USERNAME'" type="text" ng-model="typedValue" autocorrect="off" autocapitalize="off"/>
|
<input ng-show="field.type === 'USERNAME'" type="text" ng-model="typedValue" autocorrect="off" autocapitalize="off"/>
|
||||||
<input ng-show="parameter.type === 'BOOLEAN'" type="checkbox" ng-model="typedValue" autocorrect="off" autocapitalize="off"/>
|
<input ng-show="field.type === 'BOOLEAN'" type="checkbox" ng-model="typedValue" autocorrect="off" autocapitalize="off"/>
|
||||||
|
|
||||||
<!-- Password parameter -->
|
<!-- Password field -->
|
||||||
<div ng-show="parameter.type === 'PASSWORD'" class="password-field">
|
<div ng-show="field.type === 'PASSWORD'" class="password-field">
|
||||||
<input type="{{passwordInputType}}" ng-model="typedValue" autocorrect="off" autocapitalize="off"/>
|
<input type="{{passwordInputType}}" ng-model="typedValue" autocorrect="off" autocapitalize="off"/>
|
||||||
<div class="icon toggle-password" ng-click="togglePassword()" title="{{getTogglePasswordHelpText() | translate}}"></div>
|
<div class="icon toggle-password" ng-click="togglePassword()" title="{{getTogglePasswordHelpText() | translate}}"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Multiline parameter -->
|
<!-- Multiline field -->
|
||||||
<textarea ng-show="parameter.type === 'MULTILINE'" ng-model="typedValue" autocorrect="off" autocapitalize="off"></textarea>
|
<textarea ng-show="field.type === 'MULTILINE'" ng-model="typedValue" autocorrect="off" autocapitalize="off"></textarea>
|
||||||
|
|
||||||
<!-- Enumerated parameter -->
|
<!-- Enumerated field -->
|
||||||
<select ng-show="parameter.type === 'ENUM'" ng-model="typedValue" ng-options="option.value as getProtocolParameterOption(protocol.name, parameter.name, option.value) | translate for option in parameter.options | orderBy: value"></select>
|
<select ng-show="field.type === 'ENUM'" ng-model="typedValue" ng-options="option.value as getFieldOption(option.value) | translate for option in field.options | orderBy: value"></select>
|
||||||
|
|
||||||
</div>
|
</div>
|
@@ -266,9 +266,41 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
|
|||||||
$scope.parameters = {};
|
$scope.parameters = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the translation string namespace for the protocol having the
|
||||||
|
* given name. The namespace will be of the form:
|
||||||
|
*
|
||||||
|
* <code>PROTOCOL_NAME</code>
|
||||||
|
*
|
||||||
|
* where <code>NAME</code> is the protocol name transformed via
|
||||||
|
* translationStringService.canonicalize().
|
||||||
|
*
|
||||||
|
* @param {String} protocolName
|
||||||
|
* The name of the protocol.
|
||||||
|
*
|
||||||
|
* @returns {String}
|
||||||
|
* The translation namespace for the protocol specified, or null if no
|
||||||
|
* namespace could be generated.
|
||||||
|
*/
|
||||||
|
$scope.getNamespace = function getNamespace(protocolName) {
|
||||||
|
|
||||||
|
// Do not generate a namespace if no protocol is selected
|
||||||
|
if (!protocolName)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return 'PROTOCOL_' + translationStringService.canonicalize(protocolName);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given the internal name of a protocol, produces the translation string
|
* Given the internal name of a protocol, produces the translation string
|
||||||
* for the localized version of that protocol's name.
|
* for the localized version of that protocol's name. The translation
|
||||||
|
* string will be of the form:
|
||||||
|
*
|
||||||
|
* <code>NAMESPACE.NAME<code>
|
||||||
|
*
|
||||||
|
* where <code>NAMESPACE</code> is the namespace generated from
|
||||||
|
* $scope.getNamespace().
|
||||||
*
|
*
|
||||||
* @param {String} protocolName
|
* @param {String} protocolName
|
||||||
* The name of the protocol.
|
* The name of the protocol.
|
||||||
@@ -278,27 +310,7 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
|
|||||||
* protocol specified.
|
* protocol specified.
|
||||||
*/
|
*/
|
||||||
$scope.getProtocolName = function getProtocolName(protocolName) {
|
$scope.getProtocolName = function getProtocolName(protocolName) {
|
||||||
return 'PROTOCOL_' + translationStringService.canonicalize(protocolName) + '.NAME';
|
return $scope.getNamespace(protocolName) + '.NAME';
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given the internal name of a protocol and the internal name of a
|
|
||||||
* parameter for that protocol, produces the translation string
|
|
||||||
* for the localized, human-readable name of that protocol parameter.
|
|
||||||
*
|
|
||||||
* @param {String} protocolName
|
|
||||||
* The name of the protocol.
|
|
||||||
*
|
|
||||||
* @param {String} parameterName
|
|
||||||
* The name of the protocol parameter.
|
|
||||||
*
|
|
||||||
* @returns {String}
|
|
||||||
* The translation string which produces the translated name of the
|
|
||||||
* protocol parameter specified.
|
|
||||||
*/
|
|
||||||
$scope.getProtocolParameterName = function getProtocolParameterName(protocolName, parameterName) {
|
|
||||||
return 'PROTOCOL_' + translationStringService.canonicalize(protocolName)
|
|
||||||
+ '.FIELD_HEADER_' + translationStringService.canonicalize(parameterName);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,232 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 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 that allows editing of a connection parameter.
|
|
||||||
*/
|
|
||||||
angular.module('manage').directive('guacConnectionParameter', [function connectionParameter() {
|
|
||||||
|
|
||||||
return {
|
|
||||||
// Element only
|
|
||||||
restrict: 'E',
|
|
||||||
replace: true,
|
|
||||||
scope: {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.<String, String>
|
|
||||||
*/
|
|
||||||
parameters : '='
|
|
||||||
|
|
||||||
},
|
|
||||||
templateUrl: 'app/manage/templates/connectionParameter.html',
|
|
||||||
controller: ['$scope', '$injector', function connectionParameterController($scope, $injector) {
|
|
||||||
|
|
||||||
// Required services
|
|
||||||
var $q = $injector.get('$q');
|
|
||||||
var translationStringService = $injector.get('translationStringService');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The type to use for password input fields. By default, password
|
|
||||||
* input fields have type 'password', and are thus masked.
|
|
||||||
*
|
|
||||||
* @type String
|
|
||||||
* @default 'password'
|
|
||||||
*/
|
|
||||||
$scope.passwordInputType = 'password';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a string which describes the action the next call to
|
|
||||||
* togglePassword() will have.
|
|
||||||
*
|
|
||||||
* @return {String}
|
|
||||||
* A string which describes the action the next call to
|
|
||||||
* togglePassword() will have.
|
|
||||||
*/
|
|
||||||
$scope.getTogglePasswordHelpText = function getTogglePasswordHelpText() {
|
|
||||||
|
|
||||||
// If password is hidden, togglePassword() will show the password
|
|
||||||
if ($scope.passwordInputType === 'password')
|
|
||||||
return 'MANAGE.HELP_SHOW_PASSWORD';
|
|
||||||
|
|
||||||
// If password is shown, togglePassword() will hide the password
|
|
||||||
return 'MANAGE.HELP_HIDE_PASSWORD';
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Toggles visibility of the parameter contents, if this parameter
|
|
||||||
* is a password parameter. Initially, password contents are
|
|
||||||
* masked (invisible).
|
|
||||||
*/
|
|
||||||
$scope.togglePassword = function togglePassword() {
|
|
||||||
|
|
||||||
// If password is hidden, show the password
|
|
||||||
if ($scope.passwordInputType === 'password')
|
|
||||||
$scope.passwordInputType = 'text';
|
|
||||||
|
|
||||||
// If password is shown, hide the password
|
|
||||||
else
|
|
||||||
$scope.passwordInputType = 'password';
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
* <code>$scope.parameter</code> 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.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
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given the internal name of a protocol, the internal name of a
|
|
||||||
* parameter for that protocol, and the internal name for a valid
|
|
||||||
* value of that parameter, produces the translation string for the
|
|
||||||
* localized, human-readable name of that parameter value.
|
|
||||||
*
|
|
||||||
* @param {String} protocolName
|
|
||||||
* The name of the protocol.
|
|
||||||
*
|
|
||||||
* @param {String} parameterName
|
|
||||||
* The name of the protocol parameter.
|
|
||||||
*
|
|
||||||
* @param {String} parameterValue
|
|
||||||
* The name of the parameter value.
|
|
||||||
*
|
|
||||||
* @returns {String}
|
|
||||||
* The translation string which produces the translated name of the
|
|
||||||
* parameter value specified.
|
|
||||||
*/
|
|
||||||
$scope.getProtocolParameterOption = function getProtocolParameterOption(protocolName, parameterName, parameterValue) {
|
|
||||||
return 'PROTOCOL_' + translationStringService.canonicalize(protocolName)
|
|
||||||
+ '.FIELD_OPTION_' + translationStringService.canonicalize(parameterName)
|
|
||||||
+ '_' + translationStringService.canonicalize(parameterValue || 'EMPTY');
|
|
||||||
};
|
|
||||||
|
|
||||||
}] // end controller
|
|
||||||
};
|
|
||||||
|
|
||||||
}]);
|
|
@@ -24,6 +24,7 @@
|
|||||||
* The module for the administration functionality.
|
* The module for the administration functionality.
|
||||||
*/
|
*/
|
||||||
angular.module('manage', [
|
angular.module('manage', [
|
||||||
|
'form',
|
||||||
'groupList',
|
'groupList',
|
||||||
'list',
|
'list',
|
||||||
'locale',
|
'locale',
|
||||||
|
@@ -21,37 +21,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Do not stretch connection parameters to fit available area */
|
/* Do not stretch connection parameters to fit available area */
|
||||||
.connection-parameter input[type=text],
|
.connection-parameters input[type=text],
|
||||||
.connection-parameter input[type=password],
|
.connection-parameters input[type=password],
|
||||||
.connection-parameter input[type=number] {
|
.connection-parameters input[type=number] {
|
||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Keep toggle-password icon on same line */
|
|
||||||
.connection-parameter .password-field {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Generic 1x1em icon/button */
|
|
||||||
.connection-parameter .password-field .icon.toggle-password {
|
|
||||||
|
|
||||||
display: inline-block;
|
|
||||||
opacity: 0.5;
|
|
||||||
cursor: default;
|
|
||||||
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-size: 1em;
|
|
||||||
width: 1em;
|
|
||||||
height: 1em;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Icon for unmasking passwords */
|
|
||||||
.connection-parameter .password-field input[type=password] ~ .icon.toggle-password {
|
|
||||||
background-image: url('images/action-icons/guac-show-pass.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Icon for masking passwords */
|
|
||||||
.connection-parameter .password-field input[type=text] ~ .icon.toggle-password {
|
|
||||||
background-image: url('images/action-icons/guac-hide-pass.png');
|
|
||||||
}
|
|
@@ -59,17 +59,10 @@ THE SOFTWARE.
|
|||||||
|
|
||||||
<!-- Connection parameters -->
|
<!-- Connection parameters -->
|
||||||
<h2 class="header">{{'MANAGE_CONNECTION.SECTION_HEADER_PARAMETERS' | translate}}</h2>
|
<h2 class="header">{{'MANAGE_CONNECTION.SECTION_HEADER_PARAMETERS' | translate}}</h2>
|
||||||
<div class="section" ng-class="{loading: !parameters}">
|
<div class="section connection-parameters" ng-class="{loading: !parameters}">
|
||||||
<table class="properties">
|
<guac-form namespace="getNamespace(connection.protocol)"
|
||||||
|
fields="protocols[connection.protocol].parameters"
|
||||||
<!-- All the different possible editable field types -->
|
model="parameters"></guac-form>
|
||||||
<tr ng-repeat="parameter in protocols[connection.protocol].parameters">
|
|
||||||
<th>{{getProtocolParameterName(connection.protocol, parameter.name) | translate}}</th>
|
|
||||||
<td>
|
|
||||||
<guac-connection-parameter protocol="protocols[connection.protocol]" name="parameter.name" parameters="parameters"></guac-connection-parameter>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Form action buttons -->
|
<!-- Form action buttons -->
|
||||||
|
@@ -21,20 +21,20 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service which defines the ProtocolParameter class.
|
* Service which defines the Field class.
|
||||||
*/
|
*/
|
||||||
angular.module('rest').factory('ProtocolParameter', [function defineProtocolParameter() {
|
angular.module('rest').factory('Field', [function defineField() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The object returned by REST API calls when representing the data
|
* The object returned by REST API calls when representing the data
|
||||||
* associated with a configuration parameter of a remote desktop protocol.
|
* associated with a field or configuration parameter.
|
||||||
*
|
*
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {ProtocolParameter|Object} [template={}]
|
* @param {Field|Object} [template={}]
|
||||||
* The object whose properties should be copied within the new
|
* The object whose properties should be copied within the new
|
||||||
* ProtocolParameter.
|
* Field.
|
||||||
*/
|
*/
|
||||||
var ProtocolParameter = function ProtocolParameter(template) {
|
var Field = function Field(template) {
|
||||||
|
|
||||||
// Use empty object by default
|
// Use empty object by default
|
||||||
template = template || {};
|
template = template || {};
|
||||||
@@ -56,12 +56,12 @@ angular.module('rest').factory('ProtocolParameter', [function defineProtocolPara
|
|||||||
/**
|
/**
|
||||||
* The type string defining which values this parameter may contain,
|
* The type string defining which values this parameter may contain,
|
||||||
* as well as what properties are applicable. Valid types are listed
|
* as well as what properties are applicable. Valid types are listed
|
||||||
* within ProtocolParameter.Type.
|
* within Field.Type.
|
||||||
*
|
*
|
||||||
* @type String
|
* @type String
|
||||||
* @default ProtocolParameter.Type.TEXT
|
* @default Field.Type.TEXT
|
||||||
*/
|
*/
|
||||||
this.type = template.type || ProtocolParameter.Type.TEXT;
|
this.type = template.type || Field.Type.TEXT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value to set the parameter to, in the case of a BOOLEAN
|
* The value to set the parameter to, in the case of a BOOLEAN
|
||||||
@@ -75,7 +75,7 @@ angular.module('rest').factory('ProtocolParameter', [function defineProtocolPara
|
|||||||
* All possible legal values for this parameter. This property is only
|
* All possible legal values for this parameter. This property is only
|
||||||
* applicable to ENUM type parameters.
|
* applicable to ENUM type parameters.
|
||||||
*
|
*
|
||||||
* @type ProtocolParameterOption[]
|
* @type FieldOption[]
|
||||||
*/
|
*/
|
||||||
this.options = template.options;
|
this.options = template.options;
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ angular.module('rest').factory('ProtocolParameter', [function defineProtocolPara
|
|||||||
/**
|
/**
|
||||||
* All valid protocol parameter types.
|
* All valid protocol parameter types.
|
||||||
*/
|
*/
|
||||||
ProtocolParameter.Type = {
|
Field.Type = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type string associated with parameters that may contain a single
|
* The type string associated with parameters that may contain a single
|
||||||
@@ -147,6 +147,6 @@ angular.module('rest').factory('ProtocolParameter', [function defineProtocolPara
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return ProtocolParameter;
|
return Field;
|
||||||
|
|
||||||
}]);
|
}]);
|
@@ -21,20 +21,20 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service which defines the ProtocolParameterOption class.
|
* Service which defines the FieldOption class.
|
||||||
*/
|
*/
|
||||||
angular.module('rest').factory('ProtocolParameterOption', [function defineProtocolParameterOption() {
|
angular.module('rest').factory('FieldOption', [function defineFieldOption() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The object returned by REST API calls when representing a single possible
|
* The object returned by REST API calls when representing a single possible
|
||||||
* legal value of a configuration parameter of a remote desktop protocol.
|
* legal value of a field.
|
||||||
*
|
*
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {ProtocolParameterOption|Object} [template={}]
|
* @param {FieldOption|Object} [template={}]
|
||||||
* The object whose properties should be copied within the new
|
* The object whose properties should be copied within the new
|
||||||
* ProtocolParameterOption.
|
* FieldOption.
|
||||||
*/
|
*/
|
||||||
var ProtocolParameterOption = function ProtocolParameterOption(template) {
|
var FieldOption = function FieldOption(template) {
|
||||||
|
|
||||||
// Use empty object by default
|
// Use empty object by default
|
||||||
template = template || {};
|
template = template || {};
|
||||||
@@ -56,6 +56,6 @@ angular.module('rest').factory('ProtocolParameterOption', [function defineProtoc
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return ProtocolParameterOption;
|
return FieldOption;
|
||||||
|
|
||||||
}]);
|
}]);
|
@@ -57,7 +57,7 @@ angular.module('rest').factory('Protocol', [function defineProtocol() {
|
|||||||
* An array of all known parameters for this protocol, their types,
|
* An array of all known parameters for this protocol, their types,
|
||||||
* and other information.
|
* and other information.
|
||||||
*
|
*
|
||||||
* @type ProtocolParameter[]
|
* @type Field[]
|
||||||
* @default []
|
* @default []
|
||||||
*/
|
*/
|
||||||
this.parameters = template.parameters || [];
|
this.parameters = template.parameters || [];
|
||||||
|
@@ -117,6 +117,13 @@
|
|||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"FORM" : {
|
||||||
|
|
||||||
|
"HELP_SHOW_PASSWORD" : "Click to show password",
|
||||||
|
"HELP_HIDE_PASSWORD" : "Click to hide password"
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
"HOME" : {
|
"HOME" : {
|
||||||
|
|
||||||
"INFO_ACTIVE_USER_COUNT" : "@:APP.INFO_ACTIVE_USER_COUNT",
|
"INFO_ACTIVE_USER_COUNT" : "@:APP.INFO_ACTIVE_USER_COUNT",
|
||||||
@@ -161,8 +168,6 @@
|
|||||||
"FORMAT_HISTORY_START" : "@:APP.FORMAT_DATE_TIME_PRECISE",
|
"FORMAT_HISTORY_START" : "@:APP.FORMAT_DATE_TIME_PRECISE",
|
||||||
|
|
||||||
"HELP_CONNECTIONS" : "Click or tap on a connection below to manage that connection. Depending on your access level, connections can be added and deleted, and their properties (protocol, hostname, port, etc.) can be changed.",
|
"HELP_CONNECTIONS" : "Click or tap on a connection below to manage that connection. Depending on your access level, connections can be added and deleted, and their properties (protocol, hostname, port, etc.) can be changed.",
|
||||||
"HELP_SHOW_PASSWORD" : "Click to show password",
|
|
||||||
"HELP_HIDE_PASSWORD" : "Click to hide password",
|
|
||||||
|
|
||||||
"INFO_ACTIVE_USER_COUNT" : "@:APP.INFO_ACTIVE_USER_COUNT",
|
"INFO_ACTIVE_USER_COUNT" : "@:APP.INFO_ACTIVE_USER_COUNT",
|
||||||
"INFO_CONNECTION_DURATION_UNKNOWN" : "--",
|
"INFO_CONNECTION_DURATION_UNKNOWN" : "--",
|
||||||
|
Reference in New Issue
Block a user