GUAC-1160: Generate localized field headers and option values within "form" module.

This commit is contained in:
Michael Jumper
2015-04-15 15:56:20 -07:00
parent 32019e7cdf
commit e1f769fcbc
8 changed files with 136 additions and 14 deletions

View File

@@ -32,6 +32,17 @@ angular.module('form').directive('guacForm', [function form() {
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.
*
@@ -50,7 +61,10 @@ angular.module('form').directive('guacForm', [function form() {
},
templateUrl: 'app/form/templates/form.html',
controller: ['$scope', function formController($scope) {
controller: ['$scope', '$injector', function formController($scope, $injector) {
// Required services
var translationStringService = $injector.get('translationStringService');
/**
* The object which will receive all field values. Normally, this
@@ -63,6 +77,30 @@ angular.module('form').directive('guacForm', [function form() {
*/
$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) {

View File

@@ -32,6 +32,17 @@ angular.module('form').directive('guacFormField', [function formField() {
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.
*
@@ -51,6 +62,9 @@ angular.module('form').directive('guacFormField', [function formField() {
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.
@@ -72,10 +86,10 @@ angular.module('form').directive('guacFormField', [function formField() {
// If password is hidden, togglePassword() will show the password
if ($scope.passwordInputType === 'password')
return 'MANAGE.HELP_SHOW_PASSWORD';
return 'FORM.HELP_SHOW_PASSWORD';
// If password is shown, togglePassword() will hide the password
return 'MANAGE.HELP_HIDE_PASSWORD';
return 'FORM.HELP_HIDE_PASSWORD';
};
@@ -96,6 +110,37 @@ angular.module('form').directive('guacFormField', [function formField() {
};
/**
* 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,
@@ -107,7 +152,7 @@ angular.module('form').directive('guacFormField', [function formField() {
*/
var setTypedValue = function setTypedValue(modelValue) {
// Don't bother if the modelValue is not yet defined
// Don't bother if the model is not yet defined
if (!$scope.field)
return;
@@ -148,7 +193,7 @@ angular.module('form').directive('guacFormField', [function formField() {
$scope.model = typedValue.toString();
}
// Convert boolean values back into strings based on protocol description
// Convert boolean values back into strings based on field description
else if ($scope.field.type === 'BOOLEAN')
$scope.model = (typedValue ? $scope.field.value : '');

View File

@@ -23,4 +23,4 @@
/**
* Module for displaying dynamic forms.
*/
angular.module('form', []);
angular.module('form', ['locale']);

View File

@@ -23,9 +23,9 @@
<!-- All fields in form -->
<tr ng-repeat="field in fields">
<th>{{field.title | translate}}</th>
<th>{{getFieldHeader(field) | translate}}</th>
<td>
<guac-form-field field="field" model="values[field.name]"></guac-form-field>
<guac-form-field namespace="namespace" field="field" model="values[field.name]"></guac-form-field>
</td>
</tr>

View File

@@ -37,6 +37,6 @@
<textarea ng-show="field.type === 'MULTILINE'" ng-model="typedValue" autocorrect="off" autocapitalize="off"></textarea>
<!-- Enumerated field -->
<select ng-show="field.type === 'ENUM'" ng-model="typedValue" ng-options="option.value as option.title | translate for option in field.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>

View File

@@ -266,9 +266,41 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
$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
* 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
* The name of the protocol.
@@ -278,7 +310,7 @@ angular.module('manage').controller('manageConnectionController', ['$scope', '$i
* protocol specified.
*/
$scope.getProtocolName = function getProtocolName(protocolName) {
return 'PROTOCOL_' + translationStringService.canonicalize(protocolName) + '.NAME';
return $scope.getNamespace(protocolName) + '.NAME';
};
/**

View File

@@ -60,7 +60,9 @@ THE SOFTWARE.
<!-- Connection parameters -->
<h2 class="header">{{'MANAGE_CONNECTION.SECTION_HEADER_PARAMETERS' | translate}}</h2>
<div class="section connection-parameters" ng-class="{loading: !parameters}">
<guac-form fields="protocols[connection.protocol].parameters" model="parameters"></guac-form>
<guac-form namespace="getNamespace(connection.protocol)"
fields="protocols[connection.protocol].parameters"
model="parameters"></guac-form>
</div>
<!-- Form action buttons -->

View File

@@ -117,6 +117,13 @@
},
"FORM" : {
"HELP_SHOW_PASSWORD" : "Click to show password",
"HELP_HIDE_PASSWORD" : "Click to hide password"
},
"HOME" : {
"INFO_ACTIVE_USER_COUNT" : "@:APP.INFO_ACTIVE_USER_COUNT",
@@ -161,8 +168,6 @@
"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_SHOW_PASSWORD" : "Click to show password",
"HELP_HIDE_PASSWORD" : "Click to hide password",
"INFO_ACTIVE_USER_COUNT" : "@:APP.INFO_ACTIVE_USER_COUNT",
"INFO_CONNECTION_DURATION_UNKNOWN" : "--",